为什么这个执行无效指针初始化的程序在C中编译良好



我写了一个简单的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保存了它,但在这个编译器上编译失败。

此代码既不是合法的C也不是合法的C++。

N1570§6.7.9/p11:

标量的初始值设定项应为单个表达式(可选)用大括号围起来。对象的初始值是表达式(转换后);相同类型的约束和适用于简单赋值的转换,采用标量是其声明类型的非限定版本。

§6.5.16.1/p1规定,对于简单分配:

下列条件之一成立:

  • 左操作数具有原子、限定或非限定算术类型,右操作数具有算术类型
  • 左操作数具有与右操作数类型兼容的结构或并集类型的原子、限定或非限定版本
  • 左操作数具有原子、限定或非限定指针类型,并且(考虑左操作数在左值之后的类型转换)两个操作数都是指向限定或非限定的指针兼容类型的版本,左边指向的类型具有右侧所指类型的所有限定符
  • 左操作数具有原子、限定或非限定指针类型,并且(考虑左操作数在左值之后的类型转换)一个操作数是指向对象类型的指针,另一个是指向合格或不合格版本的void的指针,并且左边指向的类型具有所指向类型的所有限定符权利
  • 左操作数是原子、限定或非限定指针,右操作数是空指针常量;或
  • 左侧操作数的类型为atomic、限定或非限定_Bool,右侧为指针

其中没有一个与左边的指针和右边的333相匹配。§6.5.16.1/p1是约束,需要符合要求的实施来对违反约束产生诊断(§5.1.1.3/p1):

一致性实施应至少产生一个诊断如果预处理翻译单元或翻译单元包含违反任何语法规则或约束,即使行为也明确指定为未定义或实现定义。

碰巧GCC决定在C模式下产生一个警告而不是错误,并继续编译它,但它不必这样做。

C可以将数字转换为指针。CCD_ 4将CCD_ 5设置为指向存储器中的第123个字节。

虽然这在桌面编程中几乎毫无用处,几乎可以肯定是一个错误,但在嵌入式系统中,有必要与硬件接口,硬件可能会在某些硬编码的内存地址中查找值。

从种族角度讲,您的代码没有任何问题。您正在使用整数值333初始化指针。然后打印地址。它显示的警告可能是因为整数值被类型转换为地址类型。

当你试图取消引用指针时,问题就开始了。这会导致分割错误。

最新更新