问题
I have been prototyping a library in which I would like to use a c-string value defined locally in a function as a non-type template parameter.
In essence, the bare minimum implementation is the following (see on godbolt):
#include <cstdio>
#include <type_traits>
template <char const* C>
class compile_string {};
template <typename T>
auto foo() {
static constexpr char const CSTR[] = "Hello, World!";
return compile_string<CSTR>{};
}
int main() {
auto shorty = foo<short>();
auto inty = foo<int>();
return std::is_same_v<decltype(shorty), decltype(inty)>;
}
When compiling this short program with the latest clang (11.0), in O1 to O3 everything works well, however when compiling with O0, linking fails.
Despite the assembly section containing:
; foo<short>()::CSTR
_ZZ3fooIsEDavE4CSTR:
.asciz "Hello, World!"
; foo<int>()::CSTR
_ZZ3fooIiEDavE4CSTR:
.asciz "Hello, World!"
There is a linker error:
/opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../x86_64-linux-gnu/bin/ld:
/tmp/example-a4bb3b.o:(.debug_info+0x1be): undefined reference to `foo()::CSTR'
Passing -Xlinker --no-demangle
this error becomes:
/opt/compiler-explorer/gcc-10.2.0/lib/gcc/x86_64-linux-gnu/10.2.0/../../../../x86_64-linux-gnu/bin/ld:
/tmp/example-35000b.o:(.debug_info+0x1be): undefined reference to `_ZZ3foovE4CSTR'
Where one realizes that somehow the template parameter of foo
was stripped.
Notes:
- Gcc (7.3 and 10.2) successfully compiles this example.
- There is no reference to
_ZZ3foovE4CSTR
in the assembly -- nor to the other 2 variants, truth to be told -- which is probably why enabling optimizations "solve" the problem.
Is the above program conforming to the C++17 standard?
(And therefore am I observing an issue with the Clang compiler?)
Bonus question: and is there a work-around, to side-step the issue?
来源:https://stackoverflow.com/questions/65275694/can-a-constexpr-c-string-used-as-template-parameter-be-instantiated-in-a-templat