为什么执行无效指针初始化的程序在C中编译得很好?

Des*_*tor 3 c pointers variable-initialization

我编写了一个简单的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;
}
Run Code Online (Sandbox Code Playgroud)

访问此链接:http://ideone.com/vnKZnx

我认为由于C++的强类型检查,这个程序肯定无法在C++中编译.为什么这个程序用C编译?事实上,编译器也会显示警告.我正在使用Orwell Dev C++ IDE(gcc 4.8.1编译器).我也在其他编译器(Borland Turbo C++ 4.5)上尝试了相同的程序,通过扩展名.c保存它,并且在这个编译器上它无法编译.

T.C*_*.C. 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):

如果预处理转换单元或转换单元包含违反任何语法规则或约束的情况,则符合要求的实现应生成至少一条诊断消息(以实现定义的方式标识),即使该行为也明确指定为未定义或实现 - 定义.

碰巧GCC决定在C模式下产生警告而不是错误并继续编译它,但它没有必要.


Col*_*Two 5

C可以将数字转换为指针.char* c = 123将设置c为指向内存中的第123个字节.

虽然这几乎无用,几乎肯定是桌面编程中的错误,但在嵌入式系统中,必须与硬件接口,硬件可能在某些硬编码存储器地址中寻找值.

  • 虽然这是答案的一部分,但它没有说明为什么以及如何将此代码实际上视为违反约束,因此*每个*C编译器必须至少提供一个诊断,实际上OP承认某个地方它没有编译很好,但会发出警告. (3认同)