It seems uninitialized global variable is treated as weak symbol in Gcc. What is the reason behind this?
Share
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
gcc, in C mode:
Uninitialised globals which are not declared
externare treated as "common" symbols, not weak symbols.Common symbols are merged at link time so that they all refer to the same storage; if more than one object attempts to initialise such a symbol, you will get a link-time error. (If they aren’t explicitly initialised anywhere, they will be placed in the BSS, i.e. initialised to 0.)
gcc, in C++ mode:
Not the same – it doesn’t do the common symbols thing. "Uninitialised" globals which are not declared
externare implicitly initialised to a default value (0 for simple types, or default constructor).In either case, a weak symbol allows an initialised symbol to be overridden by a non-weak initialised symbol of the same name at link time.
To illustrate (concentrating on the C case here), I’ll use 4 variants of a main program, which are all the same except for the way that
globalis declared:main_init.c:
main_uninit.c, which omits the initialisation:
main_uninit_extern.c, which adds the
externkeyword:main_init_weak.c, which initialises
globaland declares it to be a weak symbol:and another_def.c which initialises the same global:
Using
main_uninit.con its own gives 0:but when
another_def.cis included as well,globalis explicitly initialised and we get the expected result:(Note that this case fails instead if you’re using C++.)
If we try with both
main_init.candanother.def.cinstead, we have 2 initialisations ofglobal, which won’t work:main_uninit_extern.con its own won’t work at all – theexternkeyword causes the symbol to be an ordinary external reference rather than a common symbol, so the linker complains:It works fine once the initialisation from
another_def.cis included:Using
main_init_weak.con its own gives the value we initialised the weak symbol to (999), as there is nothing to override it:But pulling in the other definition from
another_def.cdoes work in this case, because the strong definition there overrides the weak definition inmain_init_weak.c: