I'm trying to understand what I am seeing while testing a change. The platform is openSUSE 42 with GCC 4.8, but it could affect others. The test code and error follows.
$ cat test.cxx
#include <string>
#if (__cplusplus >= 201103L)
# define STATIC_CONSTEXPR static constexpr
# define CONSTEXPR constexpr
#else
# define STATIC_CONSTEXPR static const
# define CONSTEXPR
#endif
struct Name
{
STATIC_CONSTEXPR char* GetName() {return "XXX";}
};
int main(int argc, char* arv[])
{
const char* name = Name::GetName();
return 0;
}
And:
$ g++ -O3 -std=c++11 test.cxx -o test.exe
test.cxx: In static member function ‘static constexpr char* Name::GetName()’:
test.cxx:13:44: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
STATIC_CONSTEXPR char* GetName() {return "XXX";}
^
Adding the following does not clear it:
struct Name
{
STATIC_CONSTEXPR char* const GetName() {return "XXX";}
};
And adding the following does clear it:
struct Name
{
STATIC_CONSTEXPR const char* GetName() {return "XXX";}
};
According to Does static constexpr variable make sense?:
Every variable declared constexpr is implicitly const but const and static are almost orthogonal (except for the interaction with static const integers.)
I thought I mostly understood constexpr
but I'm obviously missing something (again). As I understand it, the C++ committee believes a value like "XXX"
in the reproducer can somehow change after the file is saved even though its impossible under the laws of the physical universe as we currently understand them. However, to combat the problem, they gave us constexpr
. An alternate explanation is here, but I have to admit I don't see the finer details that makes the difference.
Why am I seeing the warning, and why do I effectively need static constepr const
to squash it?
$ uname -a
Linux opensuse-42 4.1.27-27-default #1 SMP PREEMPT Fri Jul 15 12:46:41 UTC 2016 (84ae57e) x86_64 x86_64 x86_64 GNU/Linux
opensuse-42:~$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/4.8/lto-wrapper
Target: x86_64-suse-linux
Configured with: ../configure --prefix=/usr ... --host=x86_64-suse-linux
Thread model: posix
gcc version 4.8.5 (SUSE Linux)