I recently made a mistake and passed a pointer instead of a bool
, and the compiler didn't tell me anything. Is there any way to detect it?
A minimal example:
#include <iostream>
void funcion(bool variable);
void funcion(bool variable)
{
std::cout << "En funcion variable= "<< variable <<" \n";
}
int main()
{
int *b = NULL;
funcion(b);
return 0;
}
Compiled with:
g++ ejemplo.c++ -Wall -Wextra -Wdelete-non-virtual-dtor -Wswitch-default -Wshadow -Wsign-promo
-Wctor-dtor-privacy -Wcast-align -Wdisabled-optimization -Wlogical-op -Wmissing-declarations
-Wmissing-include-dirs -Wnoexcept -Woverloaded-virtual -Wredundant-decls -Wstrict-null-sentinel
-Wundef -Wformat=2 -Wunused-macros -Wno-endif-labels -Wstrict-overflow=4 -Warray-bounds=2
-Wold-style-cast -Wconversion -Wunused -Wdouble-promotion -Wformat-overflow=2
-Wno-ignored-attributes -Wattributes -Wunused-but-set-variable -Wduplicated-branches
-Wduplicated-cond -Wtrampolines -Wfloat-equal -Wshadow=global -Wunsafe-loop-optimizations
-Wpointer-arith -Wcast-qual -Wdangling-else -Wfloat-conversion -Wlogical-op -Wredundant-decls
-Wsuggest-attribute=noreturn -Wsuggest-attribute=format -Wsuggest-attribute=cold
-Wsuggest-attribute=malloc -Wsuggest-attribute=const
This compiles normally with no error or warning.
Apparently not, that is normal behavior of the type
bool
:This can be checked:
None of these calls
func()
will give any error or alert. On the other hand, if you pass the literal value, it will alert you that there are implicit conversions between floating point values /nullptr
to values of typebool
. The latter does not happen with integral values (int
andenum
which is implicitly cast toint
)If you really want to restrict the wrong data type to the function, you can use a
enum class
. These avoid implicit casting of your values to integral values. It obviously has its limitations, since it doesn't have the properties of a primitive data type. However, it can be useful to represent states.By defining the parameter in
func()
this way, you restrict that only values that were defined in theenum
Boolean (in this caseTrue
andFalse
) can be passed as arguments.As you've been told, conversion between native types and
bool
is commented out in the standard. It is also a feature that cannot be disabled.On the other hand, we have that the conversion will only be carried out when a function whose call is direct (without conversion) has not been declared.
In other words, it would suffice to declare a template that encompasses all the possible combinatorics and leave said template without implementation. If the compiler tries to use one of those functions, finding no implementation, it will throw an error at link time:
As you can see, the code will not compile until it
b
is of typebool
.Finally, since C++11 it is possible to disable some functions, the advantage of this new feature is that it is clear in the code that the function will not have an implementation because we want it to be that way, that is, it is not a oversight:
Another advantage of this last solution is that the error will be displayed at compile time, that is, we will not have to wait for the compiler to do almost all the work to find out about the error.
They are not perfect mechanisms (because sometimes you will not want to disable all possible conversions), but dealing with native types I doubt that you will find a better solution.