8

I can't understand why this code prints 1 in C, but other digit in C++?

#include <stdio.h>
static char T = 'a';
int main(int argc, char** argv) {
    struct T { char X[2]; };
    printf("size of T is %zu\n", sizeof(T));
}

And why this code prints 1 in both C and C++?

#include <stdio.h>
int main(int argc, char** argv) {
    static char T = 'a';
    struct T { char X[2]; };
    printf("size of T is %zu\n", sizeof(T));
}

Can somebody explain me this a little bit, please?

5
  • 5
    you have both a variable and a struct decl with the same name. Change the static char T to something other than T. Commented Oct 11, 2012 at 5:53
  • @WhozCraig:- thats Nikita's way....always exceptional... :) Commented Oct 11, 2012 at 5:54
  • @perilbrain lol I've apparently not been around long enough to recognize the origin of the question. I gotta pay more attention. Commented Oct 11, 2012 at 5:55
  • @WhozCraig, 2nd question is very interesting and I never knew that it really compiles Commented Oct 11, 2012 at 5:57
  • @iammilind Yeah, Zeta hit it outta the park. I didn't pick up on the local-def hiding the outter def. Nice eye on his/her part. Commented Oct 11, 2012 at 5:58

3 Answers 3

20

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.

Sign up to request clarification or add additional context in comments.

4 Comments

C has a separate name space used only for struct tag/union tag/enum. Is this true also for C++?
@Lundin: A separate name space? Usually, in C, the name of a struct name is struct name, while in C++ struct name can be used with name, as long as there isn't a local other structure/function/variable which shares the name. I wouldn't call it separate name space, but simply other naming/lookup convention.
@Zeta In C, labels, struct/union/enum tags, struct/union members and plain variables are all in different name spaces (C11 6.2.3). The C standard calls it name space, not to be confused with scope. That is why weird code like struct x { int x; } y; int x; x: compiles just fine. I merely wondered if C++ had the same "tag" concept as C.
@Lundin: Err... I'm not a language lawyer, but I guess this is the right section in C++: "Change: A C++typedef name must be different from any class type name declared in the same scope (except if the typedef is a synonym of the class name with the same name). In C, a typedef name and a struct tag name declared in the same scope can have the same name (because they have different name spaces)". Btw: only labels seem to have their own name space (see [stmt.label]).
1

In C, when a structure is declared, it is of type struct <name of struct> and not just the name of the struct. That is the reason. To avoid confusion, people use typedef to simplify the declarations in C

Comments

0

As mentioned by others, in the first snippet the local struct T will hide the static var in C++. However, to fully understand what's going on, you also have to talk about name disambiguation. In the second code snippet, struct T isn't hiding T - they're in the same scope.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.