Reputation: 6231
I have the following 3 C++ files (the problem does not occur if all are in 1 file):
clazz.hpp:
class Clazz {
public:
static const char* const NAME;
};
clazz.cpp:
#include "clazz.hpp"
const char* const Clazz::NAME = "Clazz";
main.cpp:
#include <iostream>
#include "clazz.hpp"
constexpr const char* const& get_clazz_name_ref() {
return Clazz::NAME;
}
constexpr const char* get_clazz_name() {
return Clazz::NAME; // this does not work
}
int main(void) {
std::cout << get_clazz_name_ref() << std::endl;
std::cout << get_clazz_name() << std::endl;
}
When compiling this files in Visual Studio 2015, I get an error message for the get_clazz_name
function:
error C3256: 'NAME': variable use does not produce a constant expression
Funnily enough, the function get_clazz_name_ref
is compiled OK. Why is that so?
In response to Alan Stokes https://stackoverflow.com/a/36112146/59557 : why is this working?
clazz.hpp:
#include <array>
class Clazz {
public:
static const char* const NAME;
static const size_t N = 3;
static const std::array<const char*, N> NAMES;
};
clazz.cpp:
#include "clazz.hpp"
const char* const Clazz::NAME = "Clazz";
const std::array<const char*, Clazz::N> Clazz::NAMES = {
"A",
"B",
"C"
};
main.cpp:
#include <iostream>
#include "clazz.hpp"
constexpr const char* const& get_clazz_name_ref() {
return Clazz::NAME;
}
constexpr const char* get_name(size_t i) {
return Clazz::NAMES[i];
}
int main(void) {
std::cout << get_clazz_name_ref() << std::endl;
std::cout << get_name(0) << std::endl;
}
I could change clazz.cpp
and rebuild, too.
Upvotes: 2
Views: 543
Reputation: 18974
The address of NAME
is known to the compiler when compiling main.cpp
but its value isn't. So the value can't be a compile-time constant.
(You could change clazz.cpp
only and rebuild, to give it a different value; so it can't be constant.)
That doesn't apply when they're in one file because then the initialiser is visible and the value is known.
Upvotes: 4