三元运算符的指针转换问题

时间:2011-07-25 16:54:53

标签: c++ conditional-operator null-pointer c++builder-2010 constant-expression

我知道三元运算符有一些令人惊讶的限制,但我有点困惑,因为它无法为我编译:

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

显然,这是显示问题所需的最低限度。错误是:

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

编译器是不到100%符合Embarcadero C ++ Builder 2010的,因此编译器错误绝非不可能......

注意:改变Parens以避免混淆我的意图。

注意2:我对自己如何首先得到这个结构感到有些困惑,所以这是我的借口:我在a = b? c : d这样的行上得到了一些编译错误,其中b ,c和d都是复杂的表达。为了缩小范围,我将cd替换为NULL,以便检查b是否是罪魁祸首。在这一点上,一切都在手推车里下地狱。

3 个答案:

答案 0 :(得分:23)

NULL是一个扩展为0的宏(或一些值为0的整数常量表达式,例如(1 - 1))。这不是“特别的”。

任何值为零的整型常量表达式都可用作空指针常量,这是允许int* ptr = 0;的原因。但是,这里的表达式为b ? 0 : 0;这不是一个整数常量表达式(b不是常数);其类型为int,不能隐式转换为int*

解决方法是明确指定您需要指针类型:

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

这个例子有点人为:通常当一个人使用条件运算符时,至少有一个参数实际上是一个指针类型(例如b ? ptr : 0);当其中一个操作数是指针类型时,0被隐式转换为相同的指针类型,因此整个条件表达式的类型是指针类型,而不是int

唯一可以解决这个“问题”的情况是空指针常量用作条件运算符的第二个和第三个操作数,这很奇怪。

答案 1 :(得分:4)

您的问题是,您的系统NULL被定义为0,假定它是三元运算符上下文中的int。如果你static_cast int*的一个操作数,它应该自动提升另一个操作数。

但为什么首先使用这样的结构呢?

答案 2 :(得分:3)

NULL可以定义为类型intlong,因此三元运算符具有相同的类型。没有隐式转换为指针类型,因此编译器会生成错误。 这里的问题是从常量整数表达式求值到零的隐式转换(臭名昭着的空指针常量)。

这里可能的解决方案是明确的演员:

int* ptr =  b ? (int*) NULL : NULL;