I found this example when I ran PCLint on the source code of the project I am working on. Here is the code snippet:
QString foo()
{
return false;
}
I compiled the code and verified that it returns an empty string. The real example is a large method in a large class, and somewhere in some remote if branch, there was this isolated
return false;
Ok, it is bad coding, shame on the developer (by using SVN / blame I could even find out who did this :-)) but, seriously, why doesn't the compiler complain?
My theory is that the compiler translates
return false;
to
return QString(((const char *) false));
However, I do not see all the elementary steps performed by the compiler to infer this. It first tries all the constructors of QString, and finds
QString(const * char);
but then? How does it determine that it can go from bool to const char *. Or does it automatically cast a bool to any pointer type any time you use a bool where a pointer is expected?
The second part of the question. Since all these implicit type conversions are quite dangerous (why would a developer write 'return false;' if they meant "return an empty string"?), is there a way (e.g. a compiler switch) so that such situations are at least reported as a warning? I tried -Wall in g++ and it didn't print any warning.
EDIT
Thanks for the hints. false seems to have a special treatment. If I do
return true;
I get:
error: conversion from ‘bool’ to non-scalar type ‘QString’ requested
I am using g++ 4.4.3 on Ubuntu. As pointed out in different comments, other compilers report the problem.
You can request many specific warnings with options beginning with ' -W ', for example -Wimplicit to request warnings on implicit declarations. Each of these specific warning options also has a negative form beginning ' -Wno- ' to turn off warnings; for example, -Wno-implicit .
Compiler warnings are messages produced by a compiler regarding program code fragments to be considered by the developer, as they may contain errors. Unlike compilation errors, warnings don't interrupt the compilation process.
4.3 Compiler Switches The `gcc' command accepts switches that control the compilation process. These switches are fully described in this section: first an alphabetical listing of all switches with a brief description, and then functionally grouped sets of switches with more detailed information.
gcc -Wall enables all compiler's warning messages. This option should always be used, in order to generate better code.
false
equates to zero. Zero is a special case that represents the NULL pointer, and will be cast to any pointer type without warning.
I'm quite surprised that the compiler allowed this as a one-step conversion, and didn't consider it a two-step conversion from boolean
to int
, then int
to char*
- two-step conversions aren't done implicitly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With