Discussion: Weakly Typed, Strongly Puzzling
Execute the code to understand the output and gain insights into implicit type conversions and their effects.
We'll cover the following
Run the code
Now, it’s time to execute the code and observe the output.
#include <iostream>int main(){std::cout << +!!"";}
Understanding the output
Wait, what? Is this legal C++? What does it even mean, and why does it print 1
?
While C++ is a statically typed language, it’s not particularly strongly typed. As we’ve seen throughout the course, C++ is, in fact, very eager to implicitly convert between types without explicitly telling it to. For instance, in the Aristotle’s Sum of Parts puzzle, we saw how the sum of two char
types is not a char
; in the A Strong Point puzzle, we saw how we should declare our constructors explicit
to avoid them taking part in implicit conversions; and in the A Little Sum Thing puzzle, we saw how implicit conversions between arithmetic types can lead to unexpected results.
This eagerness is something we inherited back in the day when C++ was designed as an extension of C. If we did it over today, this abundance of implicit conversions would be high on the list of things we’d want to change.
So, which implicit conversions are in play here, what is the final type of this expression, and why is the result 1
?
Breaking down the expression
Let’s discuss the expression in detail below:
Let’s start from the right, with the
""
expression. This is a string literal, and as we discussed in the String Theory puzzle, the type of a string literal is “array ofn const char
,” withn
being1
in this case (for the implicit\0
terminator).Next is the
!
operator, which negates its operand. But how do we negate an array of characters? That doesn’t make sense, does it? Indeed, it doesn’t, but the operand to the!
operator is contextually converted tobool
before being negated. Converting an array tobool
doesn’t make sense either, but as we saw in the “String Theory” puzzle, arrays can be implicitly converted to pointers, and pointers can again be converted tobool
. When a pointer is converted tobool
, it converts tofalse
if it’s a null-pointer and totrue
otherwise. Since the pointer in this case is non-null (it points to our string literal), it converts totrue
. Finally, the!
operator negates this, so we arrive atfalse
. You could argue that this entire conversion sequence doesn’t really make sense either, and we’d agree, but at least we can understand how each step works and how they combine to arrive at this result.Next up is another
!
, which, this time, simply negates our boolean valuefalse
, giving ustrue
.Finally, there’s the unary
+
. The operand to unary+
goes through integral promotions, which, forbool
, means convertingfalse
to0
andtrue
to1
. The operator itself doesn’t do anything; its result is the same as its operand (after promotion). So our boolean valuetrue
finally turns into the integer value1
, which gets printed.
Whether or not the compiler should warn about any of this is another discussion, but none of the major ones do, even with -Wall
or -Wextra
for GCC and Clang, and /Wall
for MSVC. The compiler might be able to provide some warnings, though, if we turn those warnings on explicitly. For instance, Clang will warn about the string-to-bool conversion if given the -Wstring-conversion
option (which is not included in -Wall
or -Wextra
). Check the compiler’s documentation for the list of warnings it supports.
Recommendations
Here are some recommendations to ensure better code practices and avoid confusion.
Turn on as many warnings as you can: Enable as many compiler warnings as possible to catch potential issues early.
Be aware that not all warnings are included in the maximum warning levels for each compiler: Check your compiler’s documentation to ensure that you are aware of all available warnings.
Don’t write code like this in real life: Avoid writing code that relies on complex or non-intuitive implicit conversions. It’s better to write clear and understandable code.
Level up your interview prep. Join Educative to access 70+ hands-on prep courses.