Sign in to follow this  
yacwroy

C++: global const literals & linkage

Recommended Posts

When you use global string literals consts in multiple files, what is the correct way to define them? header:
const char* intro = "abcd";
Creates multiple definitions of intro which causes linker error. header:
static const char* intro = "abcd";
Gives compiler warnings if intro isn't used (g++) - Not sure if it wastes space. header:
extern const char* intro;
source:
const char* intro = "abcd";
Works, but separates my char* constants from my int & other constants which remain in the header. Is there a better way? NOTE: Some string literals are needed by 2 or more source files. Thanks for all assistance. [Edit]: Spacing.

Share this post


Link to post
Share on other sites
Quote:
Original post by fpsgamer
In C++ const implies static. So static const is redundant.

Writing const char* intro = "abcd"; in your headers should work fine.

Did you remember to put include guards in your headers?


Well, I thought the same thing, but then I tested it, and the OP is right: The linker complains of multiple definition of the symbol.

Share this post


Link to post
Share on other sites
Quote:

In C++ const implies static. So static const is redundant.


That's what I thought. But it don't link. Try this:

header.hpp

void foo();
void zug();
const char* bar = "text";



obj.cpp

#include "header.hpp"
#include <iostream>

void foo() {
std::cout << bar;
}



more.cpp

#include "header.hpp"
#include <iostream>

void zug() {
std::cout << "else";
}



main.cpp

#include "header.hpp"
#include <iostream>

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




yacwroy@yacwroy:~/Desktop/tst$ g++ -c -o obj.a obj.cpp
yacwroy@yacwroy:~/Desktop/tst$ g++ -c -o more.a more.cpp
yacwroy@yacwroy:~/Desktop/tst$ g++ -o main.run main.cpp obj.a more.a
obj.a:(.data+0x0): multiple definition of `bar'
/tmp/ccbDD2gl.o:(.data+0x0): first defined here
more.a:(.data+0x0): multiple definition of `bar'
/tmp/ccbDD2gl.o:(.data+0x0): first defined here
collect2: ld returned 1 exit status


Now replace "const" with "static const";


yacwroy@yacwroy:~/Desktop/tst$ g++ -c -o obj.a obj.cpp
yacwroy@yacwroy:~/Desktop/tst$ g++ -c -o more.a more.cpp
yacwroy@yacwroy:~/Desktop/tst$ g++ -o main.run main.cpp obj.a more.a
yacwroy@yacwroy:~/Desktop/tst$

No error!

And ya I have include guards in my headers in my main project. It compiles fine, just won't link.

Share this post


Link to post
Share on other sites
Because const char* bar doesn't make bar a const but a pointer to a const.
You need to use:

char* const bar = "text"

or

const char* const bar = "text"

-ja

Share this post


Link to post
Share on other sites
1) Including a header in a cpp file 'pastes' the contents of the header into it at compile time.
2) Static controls scope/visibility, const controls ability to change.
3) You can't have multiple visible symbol with the same name

If you define a variable in a header, it is going to paste it into every cpp file including the header. By default, this definition is visible across modules which causes a link error.

If you use static when defining the variable, it is going to add a locally visible instance of the variable to every module. This won't generate a link error but will cause confusion; if you change the value of the variable, the change will only be visible in your module! If you don't change it, you are wasting memory as you have storage for more than one instance at a time.

externing is what you want to do here. Use static only if you want the variable to be private to the module it is in - ie you don't want to extern it.

Share this post


Link to post
Share on other sites
Quote:
Original post by yacwroy
When you use global string literals consts in multiple files, what is the correct way to define them?

I would define them like this

//header.hpp
#include <string>

const std::string foo = "bar";

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this