Search code examples
c++gcctypescastingstatic-typing

How to produce a compile-time error when caller passes a bool type to a function taking a float type in GCC/C++


Question:

What changes to the code below can be made to cause a compile-time error to occur if a bool type is passed to a function taking a float, with the following constraints:

  1. Without changing the function argument type to a bool type, because the intended type should be a floating point type, not a bool.
  2. Without requiring use of static analysis tools such as Coverity.
  3. Without requiring the caller to change in any way, such as moving the static_assert into the caller just above the call site, including all other such changes to the call site or above it.

However, changing the function signature (i.e., typically done in a header file) on the function is acceptable.

If this is absolutely impossible to do, please state the reasons why, referring to online specifications or other reference material.

Details:

Given the following C++ code:

#include <iostream>
#include <type_traits> // For std::is_same

// Function that only accepts a float
void processFloat(float value) {
  // Failed attempt of using a static assertion to ensure the input is of type float:
  static_assert(std::is_same<float, decltype(value)>::value, 
                "Error: Function processFloat can only accept float arguments.");
  std::cout << "Processing float: " << value << std::endl;
}

int main(int argc, char *argv[], char *const envp[])
{
  // processFloat(3.14f); // Valid call
  processFloat(true); // We want it to be the case that this will cause a compile-time error
  return 0;
}

Compiling and running the following code on GCC c++ version 13.3.0 using:

/usr/bin/c++ -Wall -Werror -I. main.cpp -c -o main.o
/usr/bin/c++ main.o -o main.exe
./main.exe 

emits:

Processing float: 1

See the static_assert. That intends to fail the compile with an error, but clearly it is not working. I can understand why: The type can only be known as float and so the compile continues. It is my understanding that C++ is allowed to perform this implicit type conversion from a bool to a float, so by the time the compiler reaches the static_cast line, it is too late for the misuse to be flagged as an error.

I've tried using variations of -W<something> arguments to the GCC/c++ command-line, and none of them result in a compile-time error.


Solution

  • A deleted overloaded function solves that task.

    void processFloat(bool) = delete;