ClayD

// Compiler Bug Example.cpp -- produces incorrect output in Visual Studio 2003 and 2005 for me

// clay.s.douglass_at_intel com

//

#include <iostream>

using namespace std;

#include <conio.h>

class VAddr {

public:

unsigned structure:5;

unsigned offset:29;

};

typedef union {

struct {

unsigned cmd:2; // 0 = write, 1 = read, 2-3 reserved

unsigned reqId:5;

unsigned lenCode:2; // 1 = 8 bytes, 2 = 16 bytes, 3 = 32 bytes, 0 = reserved;

VAddr va;

};

unsigned long long ll;

} MemCmd;

typedef

struct {

unsigned reqId:5;

unsigned long long data;

} MemData;

int main()

{ //int i=0;

MemCmd writeCmd = {1,2,3,{4,0}};

cout << "should be 4 is " << writeCmd.va.structure << " should be 0 is " << writeCmd.va.offset << endl;

MemData d = {writeCmd.reqId,4};

MemCmd readCmd = {1,2,3,{4,0}};

cout << "should be 4 is " << readCmd.va.structure << " should be 0 is " << readCmd.va.offset << endl;

/* prints:

should be 4 is 4 should be 0 is 0

should be 4 is 6 should be 0 is 2

*/

getch();

return 0;

}



Re: Visual C++ General Compiler bug?

Bite Qiu - MSFT

hello

Re: Compiler bug

I believe this is a compiler bug. I know one guy has tested this code, and seems repros with both VC8 SP1 and VC9, and it shows GCC 3.4.2 and 4.1.2 compile it correctly. (I haven't got so many compiler installed in my machine yet, so I am not performing this test)

I made a minimum sample code which filling the bug:

#include <iostream>

using namespace std;

typedef struct {

unsigned reqId:5;

unsigned offset:29;

} MemCmd;

typedef struct {

unsigned reqId:5;

} MemData;

int main()

{

MemCmd writeCmd = {18,7};

MemData d = {writeCmd.reqId}; // without this, works fine

MemCmd readCmd = {3,10}; // with above line of code, readCmd.offset seems always equal to writeCmd.regId;

cout << "offset should be 0 but actually equal to " << readCmd.offset << endl;

/* offset should be 0 but actually equal to 26 */

return 0;

}

Two numbers in red ( 18, 10 ) seems affect the value of readCmd.offset, change these two values will lead to different output. When look at the disassembly of MemCmd writeCmd = {18,7}; we got:

0000001d mov dword ptr [ebp-20h],12h

00000024 mov dword ptr [ebp-1Ch],7

MemCmd attempt to assign 5+29=34bits into a unsigned int, the compiler will allocate another 4bytes(Word) for MemCmd which becomes 8 bytes. So if we modify the offset bit field to 27 or lower fix the problem. But the question is, why the output value affect by the value of writeCmd.reqId(18 in this case) when offset bit field exceed unsigned int's boundary I heard something like "Both fields of readCmd appear to be getting ORed with d.reqId", With no luck I still feel confuse. So I believe it is a compiler bug which may related to the incorrect usage of register.

Regards

Rico






Re: Visual C++ General Compiler bug?

Brian Kramer

Bug reports shouldn't end here. They should land in the Connect website so that it gets the proper attention. Thanks.



Re: Visual C++ General Compiler bug?

Bite Qiu - MSFT

Brian Kramer wrote:
Bug reports shouldn't end here. They should land in the Connect website so that it gets the proper attention. Thanks.

Absolutely , I forget to mention that I've already filed a bug report in Connect website to track it.

Regards,

rico






Re: Visual C++ General Compiler bug?

Brian Kramer

Great! Thanks, Bite/rico :) Do you have a link so I can watch





Re: Visual C++ General Compiler bug?

Bite Qiu - MSFT

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx FeedbackID=259878

Next time, I will definitely attach the link in my first post if I have submited a bug report. :)






Re: Visual C++ General Compiler bug?

Bite Qiu - MSFT

This bug report has been closed with status "won't fix", here is the comments from vc++ compiler team:

unfortunately we won't be able to address it in time for the next release of Visual C++.

regards,

rico