Because in C the struct is called struct T and not only T. In C++ the local definition of struct T will hide the global variable T:
#include <stdio.h>
static char T = 'a'; // (1)
int main(int argc, char** argv) {
// `struct T` shadows outer `T` in C++
struct T { char X[2]; }; // (2)
// C: sizeof char (1); C++: sizeof struct T (2)
printf("size of T is %u\n", sizeof(T));
// C/C++: sizeof struct T (2)
printf("size of struct T is %u\n", sizeof(struct T));
}
On the other hand, when both declarations are in the same naming context, the ambiguity of the identifier T will result in the same results, since C++ expects you to specify that you really want to use the struct and not the char T:
#include <stdio.h>
int main(int argc, char** argv) {
static char T = 'a';
struct T { char X[2]; };
printf("size of T is %u\n", sizeof(T)); // sizeof (char)
printf("size of struct T is %u\n", sizeof(struct T));// sizeof struct T
}
Which results in the same size for both C and C++.
How to avoid this mistakes
Usually compilers do know that the identifier is ambiguous, but the warning is often hidden. Use compiler flags to show warnings, in GCC -Wall -Wextra are the most useful for usual programming:
test.cc: In function »int main(int, char**)«:
test.cc:5:43: Warning: unknown converting symbol »z« in format [-Wformat]
test.cc:5:43: Warning: to many arguments for format [-Wformat-extra-args]
test.cc: global:
test.cc:3:5: Warning: unused parameter »argc« [-Wunused-parameter]
test.cc:3:5: Warning: unused parameter »argv« [-Wunused-parameter]
test.cc:2:13: Warning: »T« defined, but not used [-Wunused-variable]
In this case one will see that the global static char T has been defined, but never used.