Van Nguyen
Van Nguyen

Reputation: 672

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?

Upvotes: 5

Views: 11509

Answers (5)

Mike
Mike

Reputation: 1

For C language, declare actual const in a .c file and use 'extern' for it in a header (.h) file. This should be as usual as we do when declaring a global variable.

Upvotes: 0

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361482

This one is correct,

//globals.h

extern const std::string foo; //Consistent

Consistent!

Upvotes: 5

Gene Bushuyev
Gene Bushuyev

Reputation: 5538

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";

Upvotes: 1

Leo Davidson
Leo Davidson

Reputation: 6133

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.

Upvotes: 1

Praetorian
Praetorian

Reputation: 109149

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.

Upvotes: 1

Related Questions