views:

362

answers:

4
+5  Q: 

Weird C program

Check the following code snippet

struct st
{
    struct st
    {
     int a ;
     int b ;
    } st;

    int a1 ;
} ;

struct st obj ;
struct st obj1 ;

int main()
{
    return obj.a1 + obj1.b ;
}

Microsoft's compiler Visual Studio 6.0 compiles the program succesfully. I am confused with the use of 'struct st'. What is the size of obj and obj1?

+8  A: 

GCC gives

error: nested redefinition of ‘struct st’
error: ‘struct st’ has no member named ‘a1’

If VC6 compiles this, that's fine, but this is invalid.

If you want to know the size of obj, that's sizeof obj. I'd assume VC6 just flattened out the structure and assigned it three ints.

jleedev
BTW, VC9 gives the error: error C3769: 'st' : a nested class cannot have the same name as the immediately enclosing class
Naveen
@jleedev: I guess MSVC does flatten it out - `obj1.st.st.st.st.a = 10` does affect `obj1.a`.
Jacob
BTW what is right? Should the compiler issue an error or it should compile the program successfully?
Ganesh Gopalasubramanian
@Ganesh Gopalasubramanian: The compiler should be cursing at you at this point.
Tim Post
@Tinkertim The compiler!! I hear a 'Bill' passed at some 'gates'!
Ganesh Gopalasubramanian
VC9 also compiles it succesfully! The version I used was "Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86"
Ganesh Gopalasubramanian
+1  A: 

The size of obj and obj1 are the same. The value of obj.a1 + obj1.b is undefined, since neither was initialized AND your code AND compiler are broken. If that actually BUILT, all bets are off.

NB:

That code got A LOT of 'help' from its compiler to actually work. By 'help' I mean "We have a deadline to push this out ... its bug triage time, especially where the parser is concerned!"

Tim Post
It is not true to say that they were not initialized. "Global" objects are always zero-initialized in C. Of course, this all is beside the point, since the code is not compilable.
AndreyT
@AndreyT: If that actually compiled, I think we can throw out any remnants of the standard regarding how things are treated by their scope?
Tim Post
@AndreyT: If the parser is that easily confused ... what else gives? My answer was an attempt to reflect that without angering VS fans.
Tim Post
A: 

This is not a valid C code. There's no "class scope" in C and from the point of view of C language, both definitions of struct st define the same type twice. This is illegal.

This is only well-formed as C++ code, but other than that the program simply calculates and returns 0. Why it jumps through all these hoops to return a 0 is beyond me. The program is ill-formed as C++ as well. It is illegal to declare class st as a member of class st (i.e. with the same name).

AndreyT
+1  A: 

Just having a quick glance at this makes me think that you have had defined one struct, declared two variables of type struct. Hence sizeof(obj) and sizeof(obj1) should be the same since they both are of type st! Needless to say, nested structs with same name is illegal! And surprised that it compiled. But remember, C has changed since VC 6 was out (if my memory serves me correct).

tommieb75
VS6 came out before C99 was ratified, but that's not the reason for compiling invalid code since no version of VS since has claimed to implement C99 either. I'm sure the issue is just that VS6 was not what you'd call a "pedantic" C compiler....
Steve Jessop