Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linking error due to constness of the pointer array in C++03/C++11

This issue is reproducible in the g++ prior to -std=c++14. A linking error is generated due to highlighted const shown in below codes. It disappears, if the RHS const is removed.

/* main.cpp */
const char* const arr[2] = {"Hello", "World"};
//          ^^^^^
int main () {}

and

/* foo.cpp */
extern const char* const arr[2];
//                 ^^^^^
const char* foo () { return arr[0]; }

While compiling: g++ [-std=c++11] main.cpp foo.cpp, it gives following linking error:

In function `foo()': undefined reference to `arr'  

Is it a compiler bug or a language limitation/feature?

like image 286
iammilind Avatar asked Oct 19 '22 08:10

iammilind


1 Answers

As noticed by Quentin, the draft n4296 is explicit about that in chapter 3.5 Program and linkage [basic.link] §3 (emphasize mine)

A name having namespace scope (3.3.6) has internal linkage if it is the name of
(3.1) — a variable, function or function template that is explicitly declared static; or,
(3.2) — a variable of non-volatile const-qualified type that is neither explicitly declared extern nor previously declared to have external linkage;

When you declare arr to be const, it is implicitely given internal linkage. The fix is trivial:

/* main.cpp */
extern const char* const arr[2] = {"Hello", "World"};

But best practice would recommend to have extern const char* const arr[2]; in a header included in all files using arr in order to correctly share the declaration and then add in one of those files const char* const arr[2] = {"Hello", "World"};, effectively yielding:

/* main.cpp */
extern const char* const arr[2]; // directly or more likely through an include...
...
const char* const arr[2] = {"Hello", "World"};
like image 98
Serge Ballesta Avatar answered Nov 02 '22 11:11

Serge Ballesta