According to the c++ standard:
No translation unit shall contain more than one definition of any
variable, function, class type, enumeration type, or template.
//--translation_unit.cpp--//
int a;
void foo()
{
int a; //Second defention of a. ODR fails.
}
Can you explain me how ODR does work actually?
This doesn't break the rule because you define two different variables. They have the same name, but are declared in different scopes, and so are separate entities. Each has a single definition.
The declaration in the function's scope is said to hide the one in the global namespace. Within the function, the unqualified name a refers to the local variable, while the qualified name ::a refers to the global.
They do not violate the ODR because they have different scope.
The first a has global scope
A variable that has global scope (also termed file scope) is known
throughout the file after the point where it is defined
The second a has local scope
A variable that has local scope (also termed block scope) is known
only within the block in which it is defined
For understand more clear about ODR of C++ the concepts you should investigate are: Storage Duration, Scope, and Linkage
You did not define a again.
You just defined a new variable a. It has the scope only inside the function, and has nothing to do with the original one(which has a global scope), and shadowed the original one inside the function.
Can you explain me how ODR does work actually?
Here is an example of violation of ODR:
/* file : module.cpp */
#include <stdio.h>
inline int foo() {
printf("module.foo: %p\n", &foo);
return 1;
}
static int bar = foo();
/* file : main.cpp */
#include <stdio.h>
inline int foo() {
printf("main.foo: %p\n", &foo);
return 2;
}
int main(int argc, char *argv[]) {
return foo();
}
As you can see, function int foo() defined differently in two modules. Now observe, how it produces different behavior depending on requested optimization level (O3 vs O0):
$ clang++ --std=c++11 -O0 main.cpp module.cpp && ./a.out
module.foo: 0x100a4aef0
module.foo: 0x100a4aef0
$ clang++ --std=c++11 -O3 main.cpp module.cpp && ./a.out
module.foo: 0x101146ee0
main.foo: 0x101146ee0
Output is different, because for inline functions compiler produces a linker symbol in each compilation module. This symbol (in each compilation module) is marked as "pick any, they are all the same". In the first case, when all optimizations are disabled, linker picks up definition from module.cpp. In the second case, compiler just inlines both functions so no additional work from linker is required.
There are other examples when violation of ODR produces weird behavior. So, don't do it :)
P.S. Bonus, case from real life:
/* a.cpp */
struct Rect
{
int x,y,w,h;
Rect(): x(0),y(0),w(0),h(0)
};
/* b.cpp */
struct Rect
{
double x,y,w,h;
Rect(): x(0),y(0),w(0),h(0)
};
The problem here is the same as in previous example (because Rect constructors are implicitly inline). Depending on phase of the moon compiler was picking one implementation or another producing strange results (int version will leave part of doubles uninitialized, double version will go outside of ints and corrupt memory there). Good way to protect from that is to use anonymous namespaces (C++) or declare struct as static (C):
/* file.cpp */
namespace {
struct Rect { ... };
}
/* file.c */
static struct Rect { ... };
Related
My 'Headers.h' file includes basic c++ Headers
#include <iostream>
#include <cstring>
// and many header files.
wrote a function definition for file exist check and saved it in 'common_utility.h' - ifFileExist()
common_utility.h
bool ifFileExist()
{
// ... My code
}
Wrote code for Class A
classA.h
class A
{
// Contains class A Declarations.
};
classA.cpp
// Contains
#include "Headers.h"
#include "common_utility.h"
#include "classA.h"
// class A Method definition
Wrote Code for Class B
I am using class A in Class B.
classB.h
class B
{
// Contains class A Declarations.
}
classB.cpp
// Contains
#include "Headers.h"
#include "common_utility.h"
#include "classA.h"
#include "classB.h"
// class B Method definition
// calling the function ifFileExist() in class B also.
wrote code for main program
main.cpp
// Contains
#include "Headers.h"
#include "common_utility.h"
#include "classA.h"
#include "classB.h"
// I am using class A and Class B in main program
// calling the function ifFileExist() in Main program also.
When I compile the whole program as
g++ -std=c++0x classA.cpp classB.cpp main.cpp -o main
I am getting the following error.
In function ifFileExist()': classB.cpp:(.text+0x0): multiple
definition ofifFileExist()'
/tmp/ccHkDT11.o:classA.cpp:(.text+0x2b6e): first defined here
So I decleard ifFileExist() function in Headers.h as extern.
extern bool ifFileExist();
But still I am getting the same error.
I am including 'Headers.h' in every .cpp file. That file contains basic c++ libraries. But I didn't get any mulitple definition error for that header files.
But only in my own function, I am getting the error 'multiple definition'.
I want to use 'common_utility.h' file, when ever I need to use it. If I doesn't need to use the common_utility functions in my main program, simply I should not include it.
I want my program to run in the every following cases.
g++ -std=c++0x classA.cpp main.cpp -o main
g++ -std=c++0x classB.cpp> main.cpp -o main
g++ -std=c++0x classA.cpp classB.cpp main.cpp -o main
I shouldn't get mulitple definition error at any cases. What Should I do now?
Since I could not find any complete (in my view) duplicate for this question, I am going to write a (hopefully) authoritive and complete answer.
What is One Definition Rule and why should I care
A One Definition Rule, usually dubbed ODR, is a rule which states (simplified) that any entity (informal term) used in the program should be defined once, and only once. An entity which is defined more than once is often causing a compilation or linker error, but sometimes can be left undetected by the compiler and lead to very hard-to-trace bugs.
I am not going to formally define entity here, but one can think of it as a function, variable or class. Before going further, one should very clear understand the difference between definition and declaration in C++, since while double definition is prohibited, double declaration is usually unavoidable.
Definition vs. declaration
Every entity used in the code should be declared in the given translation unit (translation unit is usually a cpp source file together with all header files included in it, directly or indirectly through other header files). The way an entitty is declared differes based on the entity itself. See below on how to declare different types of entities. Entities are often declared in header files. Since most complex application has more than one translation unit in it (more than one cpp file), and different cpp files often include the same headers, an application is likely to have multiple declarations for many entities used. Like I said above, this is not a problem.
Every entity used in the application, must be defined once and only once. The term 'application' is used a bit loosely here - for example, libraries (both static and dynamic) can have entities (at this point usually called symbols) left undefined within them, and an executable which was linked to use a dynamic library can have a symbol undefined as well. Instead, I refer to the application is an ultimate running something, after all the libraries have been statically or dynamically linked into it, and symbols resolved.
It is also worth noting that every definition serves as a declaration as well, meaning, that whenever you define something, you are also declaring the same thing.
As with declaration, the way to define an entity differes by the type of entity. Here is how one can declare/define 3 basic types of entities - variables, classes and functions - based on it's type.
Variables
Variables are declared using following construct:
extern int x;
This declares a variable x. It does not define it! A following piece of code will be compiled OK, but an attempt to link it without any other input files (for example, with g++ main.cpp) will produce a link-time error due to undefined symbols:
extern int x;
int main() {
return x;
}
The following piece of code defines variable x:
int x;
If this single line were to be put into file x.cpp, and this file compiled/linked together with main.cpp from above with g++ x.cpp main.cpp -o test it would compile and link without problems. You could even run resulting executable, and if you are to check exit code after the executable was run, you'd notice it is 0. (Since global variable x would be default-initialized to 0).
Functions
Functions are declared by providing their prototypes. A typical function declaration looks like following:
double foo(int x, double y);
This construct declares a function foo, returning double and accepting two arguments - one of type int, another of type double. This declaration can appear multiple times.
Following code defines above mentioned foo:
void foo(int x, double y) {
return x * y;
}
This definition can only appear once in the whole application.
Function definition has an additional quirk to variable definition. If above definition of foo were to put into header file foo.h, which in turn would be included by two cpp files 1.cpp and 2.cpp, which are compiled/linked together with g++ 1.cpp 2.cpp -o test you would have a linker error, saying that foo() is defined twice. This might be prevented by using following form of foo declaration:
inline void foo(int x, double y) {
return x * y;
}
Note inline there. What it tells compiler is that foo can be included by multiple .cpp files, and this inclusion should not produce linker error. Compiler have several options on how to make this happen, but it can be relied upon to do it's job. Note, it would still be an error to have this definition twice in the same translation unit! For example, following code will produce a compiler error
inline void foo() { }
inline void foo() { }
It is worth noting, that any class method defined within the class is implictly inline, for example:
class A {
public:
int foo() { return 42; }
};
Here A::foo() is defined inline.
Classess
Classess are declared by following construct:
class X;
Above declaration declares class X (and at this point X is formally called an incomplete type), so that it can be used when information about it contents, such as it's size or it's members is not needed. For example:
X* p; // OK - no information about class X is actually required to define a pointer to it
p->y = 42; // Error - compiler has no idea if X has any member named `y`
void foo(X x); // OK - compiler does not need to generated any code for this
void foo(X x) { } // Error - compiler needs to know the size of X to generate code for foo to properly read it's argument
void bar(X* x) { } // OK - compiler needs not to know specifics of X for this
A definition of class is well-known to everybody, and follows this construct:
class X {
public:
int y;
};
This makes a class X defined, and now it can be used in any context. An important note - class definition has to be unique per tralnlation unit, but does not have to be unique per application. That is, you can have X defined only once per translation unit, but it can be used in multiple files linked together.
How to properly follow ODR rules
Whenever a same entity is defined more than once in the resulting application, so-called ODR violation happenes. Most of the time, a linker will see the violation and will complain. However, there are cases when ODR violation does not break linking and instead causes bugs. This might happen, for example, when the same .cpp file defining a global variable X is put into both application and dynamic library, which is loaded on demand (with dlopen). (Yours trully spent a couple of days trying to trace a bug happened because of that.)
A more conventional causes of ODR violations are:
Same entity defined twice in the same file in the same scope
int x;
int x; // ODR violation
void foo() {
int x;
} // No ODR violation, foo::x is different from x in the global scope
Prevention: don't do this.
Same entity defined twice, when it was supposed to be declared
(in x.h)
int x;
(in 1.cpp)
#include <x.h>
void set_x(int y) {
x = y;
}
(in 2.cpp)
#include <x.h>
int get_x() {
return x;
}
While the wisdom of above code is questionable at best, in serves a point of illustrating ODR rule. In the code above, variable x is supposed to be shared between two files, 1.cpp and 2.cpp, but was coded incorrectly. Instead, the code should be following:
(in x.h)
extern int x; //declare x
(in x.xpp)
int x; // define x
// 1.cpp and 2.cpp remain the same
Prevention
Know what you are doing. Declare entities when you want them declared, do not define them.
If in the example above we'd use function instead of the variable, like following:
(in x.h)
int x_func() { return 42; }
We would have a problem which could be solved in two ways (as mentioned above). We could use inline function, or we could move definition to the cpp file:
(in x.h)
int x_func();
(in x.cpp)
int x_func() { return 42; }
Same header file included twice, causing the same class defined twice
This is a funny one. Imagine, you have a following code:
(in a.h)
class A { };
(in main.cpp)
#include <a.h>
#include <a.h> // compilation error!
The above code is seldom appearing as written, but it is quite easy to have the same file included twice through the intermediate:
(in foo.h)
#include <a.h>
(in main.cpp)
#include <a.h>
#include <foo.h>
Prevention Traditional solution to this is to use so-called include guards, that is, a special preprocessor definitions which would prevent the double-inclusion. In this regard, a.h should be redone as following:
(in a.h)
#ifndef INCLUDED_A_H
#define INCLUDED_A_H
class A { };
#endif
The code above will prevent inclusion of a.h into the same translation unit more than once, since INCLUDED_A_H will become defined after first inclusion, and will fail #ifndef on all subsequent ones.
Some compilers expose other ways to control inclusion, but to date include guards remain the way to do it uniformely across different compilers.
Before actually compiling source the compilation unit is generated from .cpp files. This basically means that all preprocessor directives are computed: all #include will be replaces with content of the included files, all #define'd values will be substituted with corresponding expressions, all #if 0 ... #endif will be removed, etc. So after this step in your case you'll get two pieces of C++ code without any preprocessor directives that will both have definition of same function bool ifFileExist() that is why you get this multiple definition error.
The fast solution is to mark it as inline bool ifFileExist(). Basically you ask compiler to replace all corresponding function calls with content of the function itself.
Another approach is to live the declaration of your function in common_utility.h and move definition to common_utility.cpp
I read in the below link that unnamed(anonymous) class should not have static data memebers in it. Could anyone please let me know the reason for it?
https://www-01.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.cbclx01/cplr038.htm
says the below..
You can only have one definition of a static member in a program.
Unnamed classes, classes contained within unnamed classes, and local
classes cannot have static data members.
All static member data, if they are ODR-used, must be defined outside the class/struct.
struct Foo
{
static int d;
};
int Foo::d = 0;
If the class/struct is unnamed, there is no way to define the member outside the class.
int ::d = 0;
cannot be used to define the static member of an unnamed class.
Update for C++17
If you are able to use C++17 or newer, you may use
static inline int d = 10;
That will allow a static member variable to be defined in an anonymous class/struct.
Sample code to demonstrate that a static member variable need not be defined outside the class definition:
#include <iostream>
struct foo
{
static inline int d = 10;
};
int main()
{
auto ptr = &foo::d;
std::cout << *ptr << std::endl;
}
Command to build:
g++ -std=c++17 -Wall socc.cc -o socc
Output of running the program:
10
Thanks are due to #Jean-MichaëlCelerier for the suggestion for the update.
Are you sure that the standard actually forbids this?
As mentioned the problem arises as you need to have an actual definition of the static member. The language provides for no method to define it. There is no other problems in referring to it as we can do it from within the struct or via an instance of it.
However GCC for example will accept the following:
static struct {
static int j;
} a;
int main() {
return a.j; // Here we actually refers to the static variable
}
but it can't be linked as a.j refers to an undefined symbol (._0::j), but there's a way to get around this. By defining it in assembler or by using compiler extensions you could. For example adding the line
int j asm("_ZN3._01jE") = 42;
Will make it work. _ZN3._01jE is the real mangled name of the static variable in this case, neither the mangled or unmangled name can be used directly as a identifier in standard C++ (but it can via GCC extension or assembler).
As you must probably realize this would only work with specific compilers. Other compilers would mangle the name in other ways (or even do other things that may make the trick not work at all).
You should really question why you would like to use this trick. If you can do the work using standard methods you should most probably chose that. For example you could reduce the visibility by using anonymous namespace instead for example:
namespace {
static struct Fubar {
static int j;
} a;
Fubar::a = 0;
}
Now Fubar is not really anonymous, but it will at least be confined to the translation unit.
When C++ was standardized, unnamed classes could not have static data members, as there was no way to define/instantiate them. However, this problem has been solved with C++11, as it added the decltype operator:
struct {
static int j;
} a;
// Declare the static member of the unnamed struct:
int decltype(a)::j = 42;
int main() {
return a.j == 42 ? 0 : 1; // Use the static member
}
So, in principle, there could be unnamed classes or structs with static data members. But the C++ standard makers deliberately did not allow this syntax, as the compiler doesn't know, which name it should give to that decltype(a)::j thing for linking. So most (all?) compilers - including current versions of GCC in normal mode - refuse to compile this.
In -fpermissive mode, GCC-9 und GCC-10 accept this code and compile it fine. However, if the declaration of a is moved to a header file, that is included from different source files, they still fail at the linking stage.
So unnamed classes can only be used inside a single translation unit. To avoid polluting the global namespace, just put anything, that needs to stay local, inside an anonymous namespace. So:
namespace {
struct whatever {
static int j;
} a;
int whatever::j = 42;
}
int main() {
return a.j == 42 ? 0 : 1;
}
compiles fine, doesn't pollute global namespace, and even doesn't lead to problems, if the name whatever clashes with a name from another header file.
I understand the use of unnamed namespaces to make functions and variables have internal linkage. Unnamed namespaces are not used in header files; only source files. Types declared in a source file cannot be used outside. So what's the use of putting types in unnamed namespaces?
See these links where it's mentioned that types can be put in unnamed namespaces:
Superiority of unnamed namespace over static?
Unnamed/anonymous namespaces vs. static functions
Why an unnamed namespace is a "superior" alternative to static?
Where do you want to put local types other than the unnamed namespace? Types can't have a linkage specifier like static. If they are not publicly known, e.g., because they are declared in a header, there is a fair chance that names of local types conflict, e.g., when two translation units define types with the same name. In that case you'd end up with an ODR violation. Defining the types inside an unnamed namespace eliminates this possibility.
To be a bit more concrete. Consider you have
// file demo.h
int foo();
double bar();
// file foo.cpp
struct helper { int i; };
int foo() { helper h{}; return h.i; }
// file bar.cpp
struct helper { double d; }
double bar() { helper h{}; return h.d; }
// file main.cpp
#include "demo.h"
int main() {
return foo() + bar();
}
If you link these three translation units, you have mismatching definitions of helper from foo.cpp and bar.cpp. The compiler/linker is not required to detect these but each type which is used in the program needs to have a consistent definition. Violating this constraints is known as violation of the "one definition rule" (ODR). Any violation of the ODR rule results in undefined behavior.
Given the comment it seems a bit more convincing is needed. The relevant section of the standard is 3.2 [basic.def.odr] paragraph 6:
There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member
of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.5) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined in more than one translation unit, then each definition of D shall consist of the same sequence of tokens; and
[...]
There are plenty of further constraints but "shall consist of the same sequence of tokens" is clearly sufficient to rule out e.g. the definitions in the demo above from being legal.
So what's the use of putting types in unnamed namespaces?
You can create short, meaningful classes with names that maybe used in more than one file without the problem of name conflicts.
For example, I use two classes often in unnamed namespaces - Initializer and Helper.
namespace
{
struct Initializer
{
Initializer()
{
// Take care of things that need to be initialized at static
// initialization time.
}
};
struct Helper
{
// Provide functions that are useful for the implementation
// but not exposed to the users of the main interface.
};
// Take care of things that need to be initialized at static
// initialization time.
Initializer initializer;
}
I can repeat this pattern of code in as many files as I want without the names Initializer and Helper getting in the way.
Update, in response to comment by OP
file-1.cpp:
struct Initializer
{
Initializer();
};
Initializer::Initializer()
{
}
int main()
{
Initializer init;
}
file-2.cpp:
struct Initializer
{
Initializer();
};
Initializer::Initializer()
{
}
Command to build:
g++ file-1.cpp file-2.cpp
I get linker error message about multiple definitions of Initializer::Initializer(). Please note that the standard does not require the linker to produce this error. From section 3.2/4:
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.
The linker does not produce an error if the functions are defined inline:
struct Initializer
{
Initializer() {}
};
That's OK for a simple case like this since the implementations are identical. If the inline implementations are different, the program is subject to undefined behavior.
I might be a bit late for answering the question the OP made but since I think the answer is not fully clear, I would like to help future readers.
Lets try a test... compile the following files:
//main.cpp
#include <iostream>
#include "test.hpp"
class Test {
public:
void talk() {
std::cout<<"I'm test MAIN\n";
}
};
int main()
{
Test t;
t.talk();
testfunc();
}
//test.hpp
void testfunc();
//test.cpp
#include <iostream>
class Test {
public:
void talk()
{
std::cout<<"I'm test 2\n";
}
};
void testfunc() {
Test t;
t.talk();
}
Now run the executable.
You would expect to see:
I'm test MAIN
I'm test 2
What you should see thought is:
I'm test MAIN
I'm test MAIN
What happened?!?!!
Now try putting an unnamed namespace around the "Test" class in "test.cpp" like so:
#include <iostream>
#include "test.hpp"
namespace{
class Test {
public:
void talk()
{
std::cout<<"I'm test 2\n";
}
};
}
void testfunc() {
Test t;
t.talk();
}
Compile it again and run.
The output should be:
I'm test MAIN
I'm test 2
Wow! It works!
As it turns out, it is important to define classes inside unnamed namespaces so that you get the proper functionality out of them when two class names in different translation units are identical.
Now as to why that is the case, I haven't done any research on it (maybe someone could help here?) and so I can't really tell you for sure. I'm answering purely from a practical standpoint.
What I would suspect though is that, while it is true that C structs are indeed local to a translation unit, they are a bit different from classes since classes in c++ usually have behavior assigned to them. Behavior means functions and as we know, functions are not local to the translation unit.
This is just my assumption.
From ISO Standard Draft: §3.0/9:
n3234 says:
A name used in more than one translation unit can potentially refer to the
same entity in these translationunits depending on the linkage (3.5) of the
name specified in each translation unit.
Can anyone explain this point with an example, please?
What is that statement actually saying? Can any one prove this point in terms of a program?
Sure! What this is saying is that if you have multiple source files (translation units) that both use some name (for example, the name of a variable, class or function), then it's possible that those different files are talking about the same variable, class, or function, assuming that that entity was declared in a way that makes it visible across different files (that is, depending on its linkage).
For example, if I have this file:
A.cpp:
int globalInt;
int main() {
globalInt = 137;
}
And this one here:
B.cpp:
extern int globalInt;
void foo() {
globalInt = 42;
}
Then in both files, the name globalInt refers to the global int variable globalInt defined in A.cpp. That's all that this point is saying.
Note, however, that if I declare globalInt without external linkage, then the two files will be talking about different variables. For example, in this case:
C.cpp:
static int globalInt;
int main() {
globalInt = 137;
}
D.cpp:
static int globalInt;
void foo() {
globalInt = 42;
}
Now the globalInt variable referenced in C.cpp is not the same as the one in D.cpp, even though they have the same name.
Hope this helps!
Ah, standards... let's obfuscate the obvious.
It's saying that, if you use a global variable with the same name in two different source files, they will be the same variable if they are extern or don't specify at all, but if any of them are declared static then those will be completely independent because they're only visible in that source file.
int a; // can be seen in other files; this may be duplicated in multiple source files
static int b; // can only be used in this file
extern int c; // explicitly using a visible variable "c" defined in another file
("Linkage" is the static/extern/default global, or auto which is almost never mentioned since it means "allocated on the stack", which is the default for variables declared inside a function and obviously not meaningful for a declaration outside a function. "Translation unit" is a common way for standards to avoid mentioning "files".)
const static int foo = 42;
I saw this in some code here on StackOverflow and I couldn't figure out what it does. Then I saw some confused answers on other forums. My best guess is that it's used in C to hide the constant foo from other modules. Is this correct? If so, why would anyone use it in a C++ context where you can just make it private?
A lot of people gave the basic answer but nobody pointed out that in C++ const defaults to static at namespace level (and some gave wrong information). See the C++98 standard section 3.5.3.
First some background:
Translation unit: A source file after the pre-processor (recursively) included all its include files.
Static linkage: A symbol is only available within its translation unit.
External linkage: A symbol is available from other translation units.
At namespace level
This includes the global namespace aka global variables.
static const int sci = 0; // sci is explicitly static
const int ci = 1; // ci is implicitly static
extern const int eci = 2; // eci is explicitly extern
extern int ei = 3; // ei is explicitly extern
int i = 4; // i is implicitly extern
static int si = 5; // si is explicitly static
At function level
static means the value is maintained between function calls.
The semantics of function static variables is similar to global variables in that they reside in the program's data-segment (and not the stack or the heap), see this question for more details about static variables' lifetime.
At class level
static means the value is shared between all instances of the class and const means it doesn't change.
It has uses in both C and C++.
As you guessed, the static part limits its scope to that compilation unit. It also provides for static initialization. const just tells the compiler to not let anybody modify it. This variable is either put in the data or bss segment depending on the architecture, and might be in memory marked read-only.
All that is how C treats these variables (or how C++ treats namespace variables). In C++, a member marked static is shared by all instances of a given class. Whether it's private or not doesn't affect the fact that one variable is shared by multiple instances. Having const on there will warn you if any code would try to modify that.
If it was strictly private, then each instance of the class would get its own version (optimizer notwithstanding).
That line of code can actually appear in several different contexts and alghough it behaves approximately the same, there are small differences.
Namespace Scope
// foo.h
static const int i = 0;
'i' will be visible in every translation unit that includes the header. However, unless you actually use the address of the object (for example. '&i'), I'm pretty sure that the compiler will treat 'i' simply as a type safe 0. Where two more more translation units take the '&i' then the address will be different for each translation unit.
// foo.cc
static const int i = 0;
'i' has internal linkage, and so cannot be referred to from outside of this translation unit. However, again unless you use its address it will most likely be treated as a type-safe 0.
One thing worth pointing out, is that the following declaration:
const int i1 = 0;
is exactly the same as static const int i = 0. A variable in a namespace declared with const and not explicitly declared with extern is implicitly static. If you think about this, it was the intention of the C++ committee to allow const variables to be declared in header files without always needing the static keyword to avoid breaking the ODR.
Class Scope
class A {
public:
static const int i = 0;
};
In the above example, the standard explicitly specifies that 'i' does not need to be defined if its address is not required. In other words if you only use 'i' as a type-safe 0 then the compiler will not define it. One difference between the class and namespace versions is that the address of 'i' (if used in two ore more translation units) will be the same for the class member. Where the address is used, you must have a definition for it:
// a.h
class A {
public:
static const int i = 0;
};
// a.cc
#include "a.h"
const int A::i; // Definition so that we can take the address
It's a small space optimization.
When you say
const int foo = 42;
You're not defining a constant, but creating a read-only variable. The compiler is smart enough to use 42 whenever it sees foo, but it will also allocate space in the initialized data area for it. This is done because, as defined, foo has external linkage. Another compilation unit can say:
extern const int foo;
To get access to its value. That's not a good practice since that compilation unit has no idea what the value of foo is. It just knows it's a const int and has to reload the value from memory whenever it is used.
Now, by declaring that it is static:
static const int foo = 42;
The compiler can do its usual optimization, but it can also say "hey, nobody outside this compilation unit can see foo and I know it's always 42 so there is no need to allocate any space for it."
I should also note that in C++, the preferred way to prevent names from escaping the current compilation unit is to use an anonymous namespace:
namespace {
const int foo = 42; // same as static definition above
}
It's missing an 'int'. It should be:
const static int foo = 42;
In C and C++, it declares an integer constant with local file scope of value 42.
Why 42? If you don't already know (and it's hard to believe you don't), it's a refernce to the Answer to Life, the Universe, and Everything.
C++17 inline variables
If you Googled "C++ const static", then this is very likely what you really want to use are C++17 inline variables.
This awesome C++17 feature allow us to:
conveniently use just a single memory address for each constant
store it as a constexpr: How to declare constexpr extern?
do it in a single line from one header
main.cpp
#include <cassert>
#include "notmain.hpp"
int main() {
// Both files see the same memory address.
assert(¬main_i == notmain_func());
assert(notmain_i == 42);
}
notmain.hpp
#ifndef NOTMAIN_HPP
#define NOTMAIN_HPP
inline constexpr int notmain_i = 42;
const int* notmain_func();
#endif
notmain.cpp
#include "notmain.hpp"
const int* notmain_func() {
return ¬main_i;
}
Compile and run:
g++ -c -o notmain.o -std=c++17 -Wall -Wextra -pedantic notmain.cpp
g++ -c -o main.o -std=c++17 -Wall -Wextra -pedantic main.cpp
g++ -o main -std=c++17 -Wall -Wextra -pedantic main.o notmain.o
./main
GitHub upstream.
See also: How do inline variables work?
C++ standard on inline variables
The C++ standard guarantees that the addresses will be the same. C++17 N4659 standard draft
10.1.6 "The inline specifier":
6 An inline function or variable with external linkage shall have the same address in all translation units.
cppreference https://en.cppreference.com/w/cpp/language/inline explains that if static is not given, then it has external linkage.
GCC inline variable implementation
We can observe how it is implemented with:
nm main.o notmain.o
which contains:
main.o:
U _GLOBAL_OFFSET_TABLE_
U _Z12notmain_funcv
0000000000000028 r _ZZ4mainE19__PRETTY_FUNCTION__
U __assert_fail
0000000000000000 T main
0000000000000000 u notmain_i
notmain.o:
0000000000000000 T _Z12notmain_funcv
0000000000000000 u notmain_i
and man nm says about u:
"u" The symbol is a unique global symbol. This is a GNU extension to the standard set of ELF symbol bindings. For such a symbol the dynamic linker will make sure that in the entire process
there is just one symbol with this name and type in use.
so we see that there is a dedicated ELF extension for this.
Pre-C++ 17: extern const
Before C++ 17, and in C, we can achieve a very similar effect with an extern const, which will lead to a single memory location being used.
The downsides over inline are:
it is not possible to make the variable constexpr with this technique, only inline allows that: How to declare constexpr extern?
it is less elegant as you have to declare and define the variable separately in the header and cpp file
main.cpp
#include <cassert>
#include "notmain.hpp"
int main() {
// Both files see the same memory address.
assert(¬main_i == notmain_func());
assert(notmain_i == 42);
}
notmain.cpp
#include "notmain.hpp"
const int notmain_i = 42;
const int* notmain_func() {
return ¬main_i;
}
notmain.hpp
#ifndef NOTMAIN_HPP
#define NOTMAIN_HPP
extern const int notmain_i;
const int* notmain_func();
#endif
GitHub upstream.
Pre-C++17 header only alternatives
These are not as good as the extern solution, but they work and only take up a single memory location:
A constexpr function, because constexpr implies inline and inline allows (forces) the definition to appear on every translation unit:
constexpr int shared_inline_constexpr() { return 42; }
and I bet that any decent compiler will inline the call.
You can also use a const or constexpr static variable as in:
#include <iostream>
struct MyClass {
static constexpr int i = 42;
};
int main() {
std::cout << MyClass::i << std::endl;
// undefined reference to `MyClass::i'
//std::cout << &MyClass::i << std::endl;
}
but you can't do things like taking its address, or else it becomes odr-used, see also: Defining constexpr static data members
C
In C the situation is the same as C++ pre C++ 17, I've uploaded an example at: What does "static" mean in C?
The only difference is that in C++, const implies static for globals, but it does not in C: C++ semantics of `static const` vs `const`
Any way to fully inline it?
TODO: is there any way to fully inline the variable, without using any memory at all?
Much like what the preprocessor does.
This would require somehow:
forbidding or detecting if the address of the variable is taken
add that information to the ELF object files, and let LTO optimize it up
Related:
C++11 enum with class members and constexpr link-time optimization
Tested in Ubuntu 18.10, GCC 8.2.0.
According to C99/GNU99 specification:
static
is storage-class specifier
objects of file level scope by default has external linkage
objects of file level scope with static specifier has internal linkage
const
is type-qualifier (is a part of type)
keyword applied to immediate left instance - i.e.
MyObj const * myVar; - unqualified pointer to const qualified object type
MyObj * const myVar; - const qualified pointer to unqualified object type
Leftmost usage - applied to the object type, not variable
const MyObj * myVar; - unqualified pointer to const qualified object type
THUS:
static NSString * const myVar; - constant pointer to immutable string with internal linkage.
Absence of the static keyword will make variable name global and might lead to name conflicts within the application.
In C++,
static const int foo = 42;
is the preferred way to define & use constants. I.e. use this rather than
#define foo 42
because it doesn't subvert the type-safety system.
To all the great answers, I want to add a small detail:
If You write plugins (e.g. DLLs or .so libraries to be loaded by a CAD system), then static is a life saver that avoids name collisions like this one:
The CAD system loads a plugin A, which has a "const int foo = 42;" in it.
The system loads a plugin B, which has "const int foo = 23;" in it.
As a result, plugin B will use the value 42 for foo, because the plugin loader will realize, that there is already a "foo" with external linkage.
Even worse: Step 3 may behave differently depending on compiler optimization, plugin load mechanism, etc.
I had this issue once with two helper functions (same name, different behaviour) in two plugins. Declaring them static solved the problem.
Yes, it hides a variable in a module from other modules. In C++, I use it when I don't want/need to change a .h file that will trigger an unnecessary rebuild of other files. Also, I put the static first:
static const int foo = 42;
Also, depending on its use, the compiler won't even allocate storage for it and simply "inline" the value where it's used. Without the static, the compiler can't assume it's not being used elsewhere and can't inline.
This ia s global constant visible/accessible only in the compilation module (.cpp file). BTW using static for this purpose is deprecated. Better use an anonymous namespace and an enum:
namespace
{
enum
{
foo = 42
};
}
Making it private would still mean it appears in the header. I tend to use "the weakest" way that works. See this classic article by Scott Meyers: http://www.ddj.com/cpp/184401197 (it's about functions, but can be applied here as well).