Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

global extern const clarification

Is declaring extern const or just extern the same thing in a header file? Also will both give external linkage?

globals.cpp

#include <string>

extern const std::string foo = "bar";

globals.h

#ifndef GLOBALS_H
#define GLOBALS_H

#include <iostream>

extern const std::string foo;

#endif  /* GLOBALS_H */

OR

globals.h

#ifndef GLOBALS_H
#define GLOBALS_H

#include <iostream>

extern std::string foo;

#endif  /* GLOBALS_H */

Both compiles and run fine, both give same address when used in multiple files, which one is more correct?

like image 509
Van Nguyen Avatar asked Dec 28 '10 15:12

Van Nguyen


4 Answers

This one is correct,

//globals.h

extern const std::string foo; //Consistent

Consistent!

like image 171
Nawaz Avatar answered Sep 21 '22 16:09

Nawaz


The correct one is

extern const std::string foo;

foo is a constant string in the source file it is defined in, so the extern declaration should indicate this too and allow the compiler to catch instances where code within source file where that header is included may try to modify foo.

like image 23
Praetorian Avatar answered Sep 22 '22 16:09

Praetorian


The only reason they both compile fine is that you are not actually using foo, so it doesn't matter whether the linker can find foo or not (it never tries to). (Or your compiler/linker is rubbish. :) )

The consistent header is fine. The one missing the const is not and will/should result in errors if something tries to use foo.

If you make some file (not globals.cpp) which includes globals.h and tries to use foo (e.g. just add a line with "foo.c_str();" into a function) then you'll get a link error because no const std::string foo could be found.

This is how it has to be, too. The header is telling anything that wants to use foo that it can only read it, not modify it. Things which include the globals.h header have no idea of what is inside globals.cpp; if you want them to treat an object as const you have to put that information in a file which they include.

like image 37
Leo Davidson Avatar answered Sep 22 '22 16:09

Leo Davidson


You can give const external linkage, as in your example, but it's still non-modifiable (constant). P.S. you need to include <string>, not <iostream>

P.P.S. If I wasn't clear, you can't redefine const-ness. This will not compile:

extern std::string foo;
extern const std::string foo = "bar";
like image 20
Gene Bushuyev Avatar answered Sep 22 '22 16:09

Gene Bushuyev