Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force `const char[]` string literals in clang

Compiling the following code

void f(char *, const char *, ...) {}
void f(const char *, ...) {}

int main()
{
    f("a", "b");
}

with clang gives me this error:

prog.cpp:6:2: error: call to 'f' is ambiguous
        f("a", "b");
        ^
prog.cpp:1:6: note: candidate function
void f(char *, const char *, ...) {}
     ^
prog.cpp:2:6: note: candidate function
void f(const char *, ...) {}
     ^

AFAIK string literals are constant in C++, and so the overload rules should drop the first variant from consideration, thus unambiguously resolving to the 2nd variant. But I guess that Clang makes them non-const for compatibility reasons (I know MSVC does that too).

What compiler flags to use to fix this? I'm already compiling with -std=c++11.

EDIT: Explicit cast to const char* solves this:

    f((const char*)"a", "b");

But if I'm correct on that the observed compiler behaviour isn't standard, I want to fix the compiler behaviour rather than the standard conforming code.

like image 683
Yakov Galka Avatar asked Aug 15 '15 11:08

Yakov Galka


1 Answers

I think this is a bug. Conversion of string literals to char * was removed in C++11 and I am not aware of any provision in overload resolution for a conversion sequence involving it.

As a workaround that does not involve changing every single call to f, you can write another overload that explicitly catches every call with a string literal, by capturing the array by reference:

template<size_t N, typename ...F>
void f(char const (&a)[N], F&&... args)
{
    f((char const *)a, std::forward<F>(args)...);
}
like image 86
M.M Avatar answered Sep 28 '22 21:09

M.M