3

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

4

3 回答 3

7

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

N1570 §6.7.9/p11:

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

§6.5.16.1/p1 规定了简单的分配:

应满足下列条件之一:

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

其中没有一个与左侧和333右侧的指针匹配。§6.5.16.1/p1 是一个约束,并且需要符合要求的实现才能在违反约束时产生诊断(§5.1.1.3/p1):

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

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

于 2014-09-08T13:37:03.500 回答
5

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

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

于 2014-09-08T13:25:19.720 回答
-2

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

当您尝试取消引用指针时,问题将开始。它会给出分段错误。

于 2014-09-08T13:29:41.997 回答