Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit internal linkage not the same as explicit internal linkage ("static")?

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)?

like image 827
Damon Avatar asked Jun 30 '11 14:06

Damon


People also ask

Is static internal linkage?

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.

What kind of linkage do static global functions have?

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.

What is internal and external linkage in C?

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.


1 Answers

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.

like image 181
Steve Jessop Avatar answered Nov 10 '22 00:11

Steve Jessop