Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is extern required for const int but not for const char*

Tags:

c++

extern

c++17

I'm confused about why I need extern or not for int vs char* in the definition in my extern.cpp file. I have the following test program:

// extern.cpp
extern const int my_int = 1;
const char* my_str = "FOO";
// main.cpp
#include <iostream>

extern const int my_int;
extern const char* my_str;

int main() {
  std::cout << my_int;
  std::cout << my_str;
  return 0;
}

If I remove the extern from extern const int my_int = 1; then I get undefined reference to 'my_int'. If I add extern to const char* my_str = "FOO"; then I get a warning 'my_str' initialized and declared 'extern'. Why do I need extern on my_int but adding it to my_str generates a warning?

This is C++17 on gcc 10.1.0. The specific commands are:

/usr/bin/g++-10  -g -std=gnu++17 -o main.cpp.o -c main.cpp
/usr/bin/g++-10  -g -std=gnu++17 -o extern.cpp.o -c extern.cpp
/usr/bin/g++-10  -g main.cpp.o extern.cpp.o -o TestExtern
like image 960
Thomas Johnson Avatar asked Jan 20 '21 16:01

Thomas Johnson


1 Answers

This is caused by different linkage of my_int and my_str variables.

my_int is a const-qualified variable in namespace scope, which means it has internal linkage by default. In other words, its visibility is limited to the current translation unit, unless you mark it extern. Additionally, internal linkage constants must have an initializer.

my_str, on the other hand, is not const-qualified. Don't be confused by the const qualifier in the pointer type, as that qualifier is part of the pointed type. The pointer itself is mutable, and you could assign it a different value in run time. Since this is a non-const variable in namespace scope, it has external linkage, and as such refers to a single pointer object in the scope of the whole program.

like image 197
Andrey Semashev Avatar answered Nov 12 '22 12:11

Andrey Semashev