26
votes

Consider the following code:

void foo(bool parameter) {
    std::cout << parameter << "\n";
}

int main() {
    foo("const char *argument");
}

I want the compiler to raise a warning when passing const char* instead of bool as a parameter to function foo.

But GCC implicitly converts it. I tried -Wall, -Wextra, and -Wpedantic, but none of these issue a warning. Is there a flag that could catch such an implicit conversion (invalid parameter type)?

Ignore the fact that the function has an argument of type bool, which some may see as bad code style. I can't refactor that part.

The standard just mentions such an implicit conversion will occur:

A prvalue of integral, floating-point, unscoped enumeration, pointer, and pointer-to-member types can be converted to a prvalue of type bool.

I know such behavior is very convenient in if (ptr) statements, but for me, in the case of passing parameters, it is clearly wrong and a source of bugs.

2
...and good for bad surprises: If there is a function which accepts std::string and another which accepts bool instead, guess which one is chosen for "const char *argument". (Spoiler alert: yes the second - and it drove me crazy until I got a clue.) ;-) - Scheff's Cat
a bit offtopic, but I am puzzled why you think having a bool parameter would be bad coding-style.. - 463035818_is_not_a_number
@user463035818 "Uncle Bob said so" could be a good reason. He argues that function with bool parameter never has a single responsibility. Uncle Bob has many strong opinions about coding though. - Yksisarvinen
@Yksisarvinen you mean that there should be a fooTrue and a fooFalse instead? Hum, maybe i could agree in some cases, but not in general, though if Bob said so there must be some truth to it - 463035818_is_not_a_number
Implicit conversions are one of the biggest mistakes in the C++ language. The implicit integer conversions are probably one of the largest general sources of bugs, outside of pointers. This is an excellent question, and kudos to you for thinking about how to design interfaces that prevent bugs in your code. - Cody Gray

2 Answers

28
votes

You could declare an overload of foo for pointers as deleted:

template <class T>
void foo(T*) = delete;

Or better yet, as @Ted comments, simply declare a vanilla overload to not compile any implicit conversions:

template <class T>
void foo(T) = delete;
16
votes

I want the compiler to raise a warning when passing const char* instead of bool as a parameter to function foo. ... I tried -Wall, -Wextra, and -Wpedantic

You need to add -Wconversion to your compiler flags. Note that seems to work with clang (recent or older version), but not with gcc.

If this triggers too many warnings that you don't want to handle, you can selectively enable -Wstring-conversion (clang only).