我编写了一个简单的C程序,我希望它在编译时会失败,但不幸的是它在C中编译并运行良好,但在C ++中编译失败。 请考虑以下计划:
#include <stdio.h>
int main()
{
char *c=333;
int *i=333;
long *l=333;
float *f=333;
double *d=333;
printf("c = %u, c+1 = %u",c,c+1);
return 0;
}
访问此链接:http://ideone.com/vnKZnx
我认为由于C ++的强类型检查,这个程序肯定不能用C ++编译。为什么这个程序用C编译?事实上,编译器也会显示警告。我正在使用Orwell Dev C ++ IDE(gcc 4.8.1编译器)。我也在其他编译器(Borland Turbo C ++ 4.5)上尝试了相同的程序,通过扩展名.c保存它,并且在这个编译器上它无法编译。
答案 0 :(得分:7)
此代码既不是合法的C也不是合法的C ++。
N1570§6.7.9/ p11:
标量的初始化程序应该是单个表达式,可选 用括号括起来。对象的初始值是 表达(转换后);相同的类型约束和 适用于简单分配的转换,采用类型 标量是其声明类型的非限定版本。
§6.5.16.1/ p1规定了简单分配:
以下其中一项应成立:
- 左操作数具有原子,限定或非限定算术类型,右边有算术类型;
- 左操作数具有与右侧类型兼容的结构或联合类型的原子,限定或非限定版本;
- 左操作数具有原子,限定或非限定指针类型,并且(考虑左值操作数在左值后的类型) 转换)两个操作数都是限定或不合格的指针 兼容类型的版本,以及左侧指向的类型 右边指出的所有类型的限定符;
- 左操作数具有原子,限定或非限定指针类型,并且(考虑左值操作数在左值后的类型) 转换)一个操作数是指向对象类型的指针,另一个是 是指向
void
的合格或非限定版本的指针 左边指向的类型具有指向的所有类型的限定符 在右边;- 左操作数是原子,限定或非限定指针,右边是空指针常量;或
- 左操作数的类型为atomic,qualified或nonqualified
_Bool
,右边是指针。
其中没有一个与左侧的指针和右侧的333
相匹配。 §6.5.16.1/ p1是约束,并且在违反约束时产生诊断需要符合实现(§5.1.1.3/ p1):
符合要求的实施应至少产生一种诊断 消息(以实现定义的方式标识)如果a 预处理翻译单元或翻译单元包含一个 违反任何语法规则或约束,即使行为是 也明确指定为未定义或实现定义。
碰巧GCC决定在C模式下产生警告而不是错误,并继续编译它,但它没有。
答案 1 :(得分:5)
C可以将数字转换为指针。 char* c = 123
会将c
设置为指向内存中的第123个字节。
虽然这几乎无用,几乎肯定是桌面编程中的错误,但在嵌入式系统中,必须与硬件接口,硬件可能会在某些硬编码的内存地址中查找值。
答案 2 :(得分:-2)
您的代码在种族方面没有任何问题。您正在使用整数常量值333初始化指针,然后打印地址。它显示的警告可能是因为整数值是类型转换为地址类型。
当您尝试取消引用指针时,问题就会开始。它会给出分段错误。