Today I encountered a pecularity which, although probably not really important, nevertheless puzzles me. Maybe I'm just not understanding C++ correctly, too.
Some arrays inside a source file point to string literals, like so:
const char* a[] = { "a", "b", "c" };
const char* b[] = { "d", "e"};
const char* c[] = { "f", "g"};
None of these pointer arrays is ever used in any way other than being passed to GetProcAddress
to retrieve a function pointer from a library (this is a non-blocking dynamic OpenAL/EFX/capture function loader and context creator/manager).
It eventually occurred to me that I should probably declare those variables as static const
since they're not needed anywhere outside that very .cpp file, so making internal linkage explicit seemed appropriate. They should have internal linkage anyway (ISO14882 3.5(3)), so we're only being good citizens by making explicit what the compiler already assumes.
Doing that innocent change resulted in a 512 byte increase of executable size. Not like an additional 512b really matter, but it just didn't seem to make sense that the exact same thing would result in different code. Since static const
is deprecated (ISO14882 7.3.1.1(2)), I tried an anonymous namespace also, with the same result.
Looking at the assembler source shows that explicit internal linkage (static
or namespace{}
) will move the string literals into .rdata
rather than .data
, and the string literals are interleaved with pointer-to-string-literal arrays, instead of having all strings and all pointers in one block, respectively. Herein probably lies the reason for the different size too -- very likely shuffling data from one section to another has hit a section size constraint. Interestingly, all 3 flavours mangle the names differently too.
Now I wonder: Am I making a fallacy, should those pointers not have internal linkage?
Also, in my understanding const
is already read-only, inhowfar is static const
"more read-only" (one goes into .rdata
and the other does not)?
The scope of a global variable can be restricted to the file containing its declaration by prefixing the declaration with the keyword static . Such variables are said to have internal linkage.
The static keyword, when used in the global namespace, forces a symbol to have internal linkage. The extern keyword results in a symbol having external linkage.
Both are decided by linkage. Linkage thus allows you to couple names together on a per file basis, scope determines visibility of those names. There are 2 types of linkage: Internal Linkage: An identifier implementing internal linkage is not accessible outside the translation unit it is declared in.
Your arrays are not declared const
, hence they aren't implicitly internal linkage either. What you have is non-const arrays of pointers-to-const.
That said, I don't know why this affects whether the strings end up in .rdata
or .data
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With