Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't this "undefined extern variable" result in a linker error in C++17?

I have compiled and ran the following program in a C++17 compiler (Coliru). In the program, I declared an extern variable, but did not define it. However, the compiler doesn't give a linker error.

#include <iostream>  extern int i; // Only declaration  int func()  {     if constexpr (true)         return 0;     else if (i)         return i;     else         return -1; }  int main()  {     int ret = func();     std::cout<<"Ret : "<<ret<<std::endl; } 

Why doesn't the compiler give a linker error?

like image 761
msc Avatar asked Jul 11 '17 07:07

msc


People also ask

What causes linker error?

Linker errors occur when the linker is trying to put all the pieces of a program together to create an executable, and one or more pieces are missing. Typically, this can happen when an object file or libraries can't be found by the linker.

How do you fix a linker error?

You can fix the errors by including the source code file that contains the definitions as part of the compilation. Alternatively, you can pass . obj files or . lib files that contain the definitions to the linker.

Can we change value of extern variable in C?

External variables are also known as global variables. These variables are defined outside the function. These variables are available globally throughout the function execution. The value of global variables can be modified by the functions.

What does C extern mean?

extern "C" specifies that the function is defined elsewhere and uses the C-language calling convention. The extern "C" modifier may also be applied to multiple function declarations in a block. In a template declaration, extern specifies that the template has already been instantiated elsewhere.


2 Answers

Because the variable isn't odr-used. You have a constexpr if there that always discards the branch that could use it.

One of the points of constexpr if is that the discarded branch need not even compile, only be well-formed. That's how we can place calls to non-existing member functions in a discarded branch.

like image 167
StoryTeller - Unslander Monica Avatar answered Sep 20 '22 05:09

StoryTeller - Unslander Monica


In your case the variable is used in discarded statements only. However, even if we ignore that fact, C++ language specification still explicitly states that no diagnostic is required for missing definitions

3.2 One-definition rule

4 Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement (6.4.1); no diagnostic required.

The language specification understands that an optimizing compiler might be smart enough to eliminate all odr-uses of a variable. In that case it would be excessive and unnecessary to require the implementation to detect and report the potential ODR violations.

like image 24
AnT Avatar answered Sep 21 '22 05:09

AnT