Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing int as bool argument in C++

could someone explain what happens in this code:

example here: https://ideone.com/1cFb4N

#include <iostream>

using namespace std;

class toto
{
public:
    bool b;
    toto(bool x)
    {
        cout<< "constructor bool:" << (x ? "true": "false")<<endl;
        b = x;
    }
    ~toto() {}
};

int main()
{
    toto t = new toto(0);
    cout << "t.b is " << (t.b ? "true": "false")<<endl;
    t = new toto(false);
    cout << "t.b is " << (t.b ? "true": "false")<<endl;
    return 0;
}

output:

constructor bool:false
constructor bool:true
t.b is true
constructor bool:false
constructor bool:true
t.b is true
like image 634
serge Avatar asked Oct 07 '20 21:10

serge


People also ask

Can you assign an int to a bool?

Yes, you can assign an integer value to an integer variable. Just make sure the value fits into the variable.

Is bool always 0 or 1?

Boolean values and operations C++ is different from Java in that type bool is actually equivalent to type int. Constant true is 1 and constant false is 0. It is considered good practice, though, to write true and false in your program for boolean values rather than 1 and 0.

Which is faster bool or int?

Surprisingly, g(bool) generates more asm instructions! Does it mean that if(bool) is little slower than if(int) ? I used to think bool is especially designed to be used in conditional statement such as if , so I was expecting g(bool) to generate less asm instructions, thereby making g(bool) more efficient and fast.

How do you pass an array as an argument in C?

Passing Arrays as Function Arguments in C. If you want to pass a single-dimension array as an argument in a function, you would have to declare a formal parameter in one of following three ways and all three declaration methods produce similar results because each tells the compiler that an integer pointer is going to be received.

How do you use a bool variable in C?

Use of bool in C. Prerequisite: Bool Data Type in C++. The C99 standard for C language supports bool variables. Unlike C++, where no header file is needed to use bool, a header file “stdbool.h” must be included to use bool in C. If we save the below program as .c, it will not compile, but if we save it as .cpp, it will work fine.

How to declare a Boolean data type in C?

To declare a boolean data type in C we have to use a keyword named bool followed by a variable name. bool var_name; Here, keyword bool is the data type of variable and var_name is the variable. A bool takes in real 1 bit, as we need only 2 different values (0 or 1).

What are the parameter passing techniques in C++?

Parameter Passing Techniques in C/C++. There are different ways in which parameter data can be passed into and out of methods and functions. Let us assume that a function B() is called from another function A(). In this case A is called the “caller function” and B is called the “called function or callee function”.


3 Answers

In this declaration

toto t = new toto(0);

the object t of the class type toto is initialized by the pointer returned by the expression new toto(0). As the returned pointer is not equal to nullptr then it is implicitly converted to the boolean value true.

So in fact you have

toto t = true;

except that there is a memory leak because the address of the allocated object is lost. So the allocated object can not be deleted.

You could imagine the declaration above the following way.

toto *ptr = new toto(0)
toto t = ptr;

So the first line of this output

constructor bool:false
constructor bool:true

corresponds to the dynamically created object with the argument 0

new toto(0)

Then the returned pointer is used as an initializer and is implicitly converted to the boolean value true that is used to initialize the declared object t. So the second line shows the call of the conversion constructor (constructor with a parameter) with the value true.

There is no great difference between the above declaration and this assignment statement

t = new toto(false);

because again a pointer is used in the right hand of the assignment.

So the implicitly defined copy assignment operator converts the value of the pointer that is not equal to nullptr to the boolean value true.

This assignment you may imagine the following way

toto *ptr = new toto(false);
t = toto( ptr );

And again there is a memory leak.

From the C++ 14 Standard (4.12 Boolean conversions)

1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. For direct-initialization (8.5), a prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.

like image 171
Vlad from Moscow Avatar answered Oct 19 '22 20:10

Vlad from Moscow


Any integer value is implicitly convertible to bool, with 0 converting to false, and all other values converting to true.

The same applies to pointers, with null pointers converting to false, and all others converting to true.

toto t = new toto(0); is equivalent to:

// Create new toto instance, convert 0 to false and assign to p
toto* p = new toto(0);
// Create toto instance on the stack and convert non-null pointer p to true
toto t = toto(p);

You can prevent these surprising conversions by marking single argument constructors as explicit, meaning they won't be allowed to be considered during implicit conversions:

class toto
{
public:
    bool b;
    explicit toto(bool x)
    {
        cout<< "constructor bool:" << (x ? "true": "false")<<endl;
        b = x;
    }
    ~toto() {}
};
like image 20
Alan Birtles Avatar answered Oct 19 '22 19:10

Alan Birtles


In this statement:

toto t = new toto(0);

in the expression new toto(0) you are allocating a toto with a default argument 0. This int can be implicitly converted to the bool value false, and this calls the bool constructor, resulting in the output:

constructor bool:false

Then you are doing the assignment:

toto t = /* pointer returned by new */;

This pointer can be implicitly converted to bool, and since this pointer is not nullptr, it has a non-zero value. This combined with the fact that the toto constructor accepting a bool is not explicit means that the constructor from bool is called for t, resulting in:

constructor bool:true

and this makes the b member of t have the value true, and hence the next line of code results in the output:

t.b is true
like image 19
cigien Avatar answered Oct 19 '22 21:10

cigien