Question

I know the ternary operator has some surprising restrictions, but I was a bit baffled that this fails to compile for me:

void foo(bool b)
{
    int* ptr =  ((b) ? NULL : NULL);
}

Obviously that's the minimum needed to show the problem. The error is:

[BCC32 Error] Unit11.cpp(20): E2034 Cannot convert 'int' to 'int *'

Compiler is the less-than-100%-conforming Embarcadero C++Builder 2010, so a compiler bug is far from impossible...

NOTE: Parens modified to avoid confusion about my intent.

NOTE2: I'd got myself a little confused about how I'd arrived at this construct in the first place, so here's my excuse: I was getting some compilation errors on a line like a = b? c : d, where b, c and d were all complex expressions. To narrow it down, I replaced c and d with NULLs in order to check if b was the culprit. At this point, everything went to hell in a handcart.

Was it helpful?

Solution

NULL is a macro that expands to 0 (or some integral constant expression with a value of 0, for example, (1 - 1)). It's not otherwise "special."

Any integral constant expression with a value of zero is usable as a null pointer constant, which is the reason that int* ptr = 0; is permitted. However, here, the expression is b ? 0 : 0; this is not an integral constant expression (b is not constant); its type is int, which is not implicitly convertible to int*

The workaround would be to explicitly specify that you want a pointer type:

int* const null_int_ptr = 0;
int* ptr = b ? null_int_ptr : null_int_ptr;

The example is a bit contrived, though: usually when one uses the conditional operator, at least one of the arguments is actually a pointer type (e.g. b ? ptr : 0); when one of the operands is a pointer type, the 0 is implicitly converted to that same pointer type and thus the type of the entire conditional expression is the pointer type, not int.

The only case where you can have this "problem" is where a null pointer constant is used as both the second and third operands of the conditional operator, which is rather odd.

OTHER TIPS

Your problem is that on your system NULL is defined to be 0 which is assumed to be an int in the context of the ternary operator. If you static_cast one of the operands to int* it should auto-promote the other one.

But why are using such a construct in the first place?

NULL could be defined as having type int or even long, so the ternary operator has the same type. There's no implicit conversion to the pointer type, so compiler generates an error. The gotcha here is that there is an implicit conversion from constant integer expression evaluating to zero (the infamous null pointer constant).

Possible solution here is an explicit cast:

int* ptr =  b ? (int*) NULL : NULL;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top