17

The given C code

#include <stdio.h>
int x = 14; 
size_t check()
{
   struct x {};
   return sizeof(x); // which x
}
int main()
{
    printf("%zu",check()); 
    return 0;
}

gives 4 as output in C on my 32 bit implementation whereas in C++ the code

#include <iostream>
int x = 14;    
size_t check()
{
   struct x {};
   return sizeof(x); // which x    
}
int main()
{
    std::cout<< check(); 
    return 0;
}

outputs 1. Why such difference?

Mohit Khullar
  • 245
  • 2
  • 6
  • 1
    Possible duplicates: http://stackoverflow.com/questions/3451266/understanding-sizeofchar-in-32-bit-c-compilers http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member – phooji Mar 19 '11 at 08:44
  • 2
    @phooji: No, that's not a duplicate. – Saurabh Manchanda Mar 19 '11 at 08:46
  • @Saurabh: You may be right -- the questions don't cover exactly the same ground, but I think the answers are pertinent (see Prasoon's answer and also my comment to your answer). – phooji Mar 19 '11 at 08:51

3 Answers3

26

In C++ class declaration struct x {}; introduces the name x into the scope of check and hides x (previously declared as int at file scope). You get 1 as the output because size of empty class cannot be zero in C++.

In C, an inner scope declaration of a struct tag name never hides the name of an object or function in an outer scope.You need to use the tag name struct to refer to the typename x (struct). However you can't have an empty struct in C as it violates the syntactical constraints on struct(however gcc supports it as an extension).

Community
  • 1
  • 1
Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
  • 6
    +1, but perhaps one should emphasize the fact that in C++ `struct x` only hides the variable because `x` is declared in the outer scope. If they were declared in the same scope they would happily live together *and* the behavior of the `sizeof` would be the same as for C. – Jens Gustedt Mar 19 '11 at 09:12
8

The C code is giving you the size of the global variable 'x', whereas the C++ code is giving the size of the empty struct. To get the size of the struct x in the C code, use sizeof(struct x)

Saurabh Manchanda
  • 1,115
  • 1
  • 9
  • 21
  • You are right about the scoping issue, but it's not the whole story. In particular, now the question becomes: why does `sizeof(struct x)` yield 0 in the C version :) – phooji Mar 19 '11 at 08:52
  • @phooji : Empty struct in C is a constraint violation. – Prasoon Saurav Mar 19 '11 at 08:53
  • 1
    @phooji: As C doesn't allow empty structs and hence, the construct in the above program being invalid, I don't think arguing over the same would be very beneficial. – Saurabh Manchanda Mar 19 '11 at 08:59
7

In C, struct tags live in a separate name space, and you have to use the struct keyword to access names in there. This is the reason that the "typedef struct {} x" idiom is so popular in C--it allows you to essentially promote struct names to the global namespace.

In C++, by contrast, structs (and all other names) live in the namespace surrounding the declaration, rather than a separate struct tag namespace as in C.

As Saurabh said, use sizeof(struct x) in C, or use the typedef struct {} x trick to get sizeof(x) to work as in C++.

As an added bonus, the C++ program outputs 1 because concrete class objects must have nonzero size (so that different objects must have different addresses), so the compiler has padded the struct with an anonymous char value.

Drew Hall
  • 28,429
  • 12
  • 61
  • 81