0

I have a simple config struct defined in a header that contains a series of other simple structs that are just containers for static variables. Here's an example:

// Config.h struct Config { struct Server { static constexpr const char* url = "http://example.com"; static constexpr float polling_interval = 1.0f; }; struct Window { static constexpr int width = 1920; static constexpr int height = 1200; }; }; 

I include the header file where I need it and access the variables like this: Config::Window::width

This works fine but at a certain point I needed to load the values from a file so I changed the variable declarations to not be constants (e.g. static constexpr int width = 1920; became static int width;). Now the linker complains of undefined symbols for the variables. Isn't the linkage for static constexpr objects the same as for static objects? Is there something else I'm missing?

3 Answers 3

1

It has nothing to do with linkage.

Static constants, with a value specified in their declaration, are usable as constant expressions, and don't need definitions for that usage.

Static variables do need definitions if they aren't constant (so the value needs to be stored somewhere at runtime) or if they're odr-used (roughly speaking, if you take their address or form a reference to them, which again means they need to exist somewhere at runtime).

Sign up to request clarification or add additional context in comments.

Comments

1

You are missing the definitions of the non-constexpr members. In .cpp file you need to have e.g.

int Config::width; 

Comments

1

constexpr members are implicitly inline, and thus need no definition. Once they are proper variables though, you need to allocate them in a translation unit (.cpp).

3 Comments

and thus need no definition? Rather, and thus must be defined in any TU in which they are used. Also, that's only about functions/ctors.
"inline" is a somewhat confusing term for a variable. They're usable as constant expressions, and only need a definition if they're odr-used (roughly speaking, if you need their address).
Well, it certainly confused Deduplicator. @Himself : what I called an "inline" constant is one whose value is just dropped in place by the compiler wherever it appears. This behaviours removes the need for a definition (allocation), because the variable doesn't exist per se.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.