为什么我可以隐式地将int文字转换为C中的int *而不是C ++中的int *?

我相信在下面的代码中,C“自动将17转换为int * ”,正如有人最近指出的那样(但没有说明原因),这是错误的。

 int *ptoi = 17; // I assumed that 17 is being automatically casted to int * 

我知道如果我在C ++中执行与上面相同的操作,我会收到一条错误,指出invalid conversion from int to int * 。 但是,如果我在C ++中执行以下操作,它可以正常工作:

 int *ptoi = (int *)17; 

这些是我认为在C中,铸造是隐含的原因。

有人可以解释为什么,在C ++中,我必须使用它,但在C中,它工作正常吗?

从整数到没有强制转换的指针的转换在C中也是非法的。大多数编译器会让你逃脱它。 Clang发出警告:

 example.c:5:8: warning: incompatible integer to pointer conversion initializing 'int *' with an expression of type 'int' int *x = 17; ^ ~~ 

C99在第6.5.4节演员操作员第4段中说:

除了6.5.16.1的约束允许之外,涉及指针的转换应通过显式转换来指定。

6.5.16.1是void *转换为其他指针而不需要强制转换的例外。

C ++规范在第5.4节显式类型转换(强制转换表示法)第3段中说明:

下面未提及且未由用户明确定义的任何类型转换都是错误的。

所以你去 – 两种语言都是非法的,但为了与许多旧软件兼容,很多C编译器都会让你逃脱它。

是的,虽然许多(所有?)编译器发出警告,但是C中隐含了强制转换。 在C ++中,没有从intint*执行隐式转换,因此需要显式转换。

一直以来,C都有隐含的转换 – 根据我的经验,几乎从任何整数类型到任何其他整数类型。 C中的指针被认为是整数 scalar类型。

在C ++中,积分类型定义如下:

类型boolcharchar16_tchar32_twchar_t以及有signedunsigned整数类型统称为整数类型。 48整数类型的同义词是整数类型。 整数类型的表示应使用纯二进制计算系统定义值。 49 [例子:本国际标准允许积分类型的2的补码,1的补码和带符号的幅度表示。 – 示例]

可以在C ++中转换为指针类型的唯一整数值​​是空指针常量 ,但从技术上讲,转换是std::nullptr_t类型的prvalue 。 (第4.10段)

最后的说明

而不是像这样修复它:

 int *ptoi = (int *)17; 

考虑添加C ++风格的强制转换:

 int *ptoi = reinterpret_cast(17); 

清楚地说明您要调用的转换类型

编译器将解释int *ptoi = 17; 作为变量ptoi,指向位置17处的整数(0x00000011)。

C只是一种完全不同的语言。 它可能看起来像C ++,但事实并非如此。 不同的规则适用于这两种语言。

我应该指出,C和C ++都会(据我所知)使它成为指向0x00000011的指针,但C只是抱怨较少,因为在C中分配内存位置是无效的。