Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to avoid inadvertently passing a non-boolean argument to a boolean parameter?

Tags:

c++

I got bit by a C++ type-safety issue today, and I'm wondering if there is a good way to get the compiler to detect this issue at compile time. Consider this example code:

class Bar
{
public:
   void Foo(bool arg1 = false, int arg2 = 10, int arg3 = 20)
   {
      [...]
   }
};

int main(int argc, char ** argv)
{
   int x = 40, y = 50;
   Bar b;
   b.Foo();            // correct usage
   b.Foo(true, x, y);  // correct usage
   b.Foo(x, y);        // problem:  compiles but won't do what the caller expects
}

As shown in the final call to b.Foo(), the issue is that it's easy to forget to supply the first argument, and in that case things go wrong in a way that is not caught by the compiler.

What would be nice is if I could get the compiler to say something like "ERROR, non-boolean value was supplied to a boolean parameter". That would force the developer to examine the code, and if he really wanted to pass in x as a boolean, he'd have to pass in (x!=0) instead.

This seems like a good place to use the "explicit" keyword, but AFAICT that keyword doesn't work for function arguments.

(I realize that this sort of issue could be avoided by not supplying default values for the arguments, but default values can be quite handy)

like image 721
Jeremy Friesner Avatar asked Jan 29 '15 22:01

Jeremy Friesner


People also ask

Why are Boolean parameters bad?

Boolean params make code harder to change And this just calls for more. Now, chances are high that someone will have to use the function again, with another slightly different behavior. Another parameter will get added. Because it will feel like the simplest thing to do.

Is it wrong to use a Boolean parameter to determine behavior?

Though it is technically correct to use Boolean parameters, it violates the Single Responsibility Principle and functional cohesion that helps to achieve a single, well-defined purpose to the function. It means that based on a Boolean value, the function does two different things.

Are Boolean flags bad?

Flags are not a best practice because they reduce the cohesion of a function. It does more than one thing. Booleans make it hard to understand what a function does based on the call site. Single argument functions and passing an object with named values improves the readability.


1 Answers

You may provide deleted overloads:

class Bar
{
public:
   void Foo(bool arg1 = false, int arg2 = 10, int arg3 = 20)
   {
      [...]
   }

    template <typename T>
    void Foo(T&&, int = 10, int = 20) = delete;
};

As the template method would be an exact match for non bool parameter.

like image 77
Jarod42 Avatar answered Nov 09 '22 21:11

Jarod42