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

发布于 2024-11-26 12:19:59 字数 565 浏览 2 评论 0原文

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

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 是否是罪魁祸首。至此,一切都陷入了手车地狱。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

治碍 2024-12-03 12:19:59

NULL 是一个扩展为 0 的宏(或某个值为 0 的整型常量表达式,例如 (1 - 1))。否则它并不“特别”。

任何值为 0 的整型常量表达式都可以用作空指针常量,这就是允许 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

唯一可能出现此“问题”的情况是使用空指针常量作为条件运算符的第二个和第三个操作数,这相当奇怪。

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.

没企图 2024-12-03 12:19:59

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

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

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?

愿与i 2024-12-03 12:19:59

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

这里可能的解决方案是显式强制转换:

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

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文