为什么这个执行无效指针初始化的程序在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; } #包括 int main() { char*c=333; int*i=333; 长*l=333; 浮点数*f=333; 双*d=333; printf(“c=%u,c+1=%u”,c,c+1); 返回0; }

为什么这个执行无效指针初始化的程序在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; } #包括 int main() { char*c=333; int*i=333; 长*l=333; 浮点数*f=333; 双*d=333; printf(“c=%u,c+1=%u”,c,c+1); 返回0; },c,pointers,variable-initialization,C,Pointers,Variable Initialization,请访问此链接: P>我认为,C++的强大类型检查,这个程序绝对不能编译在C++中。为什么这个程序用C编译?事实上,编译器也会显示警告。我正在使用奥威尔DEV C++ IDE(GCC 4.8-1编译器)。我还尝试了其他编译器(Borland Turbo C++ 4.5)的程序,用扩展名C保存它,在这个编译器上编译失败。code>char*c=123将c设置为指向内存中的第123个字节 虽然这几乎毫无用处,而且几乎可以肯定是桌面编程中的错误,但在嵌入式系统中,有必要与硬件接口,硬件可能会在某些硬编

请访问此链接:


<> P>我认为,C++的强大类型检查,这个程序绝对不能编译在C++中。为什么这个程序用C编译?事实上,编译器也会显示警告。我正在使用奥威尔DEV C++ IDE(GCC 4.8-1编译器)。我还尝试了其他编译器(Borland Turbo C++ 4.5)的程序,用扩展名C保存它,在这个编译器上编译失败。code>char*c=123将
c
设置为指向内存中的第123个字节


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

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


当您尝试取消对指针的引用时,问题将开始出现。这将导致分割错误

>此代码既不是合法的C,也不是合法的C++。 N1570§6.7.9/p11:

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

§6.5.16.1/p1规定,对于简单转让:

下列情况之一应适用:

  • 左操作数具有原子、限定或非限定算术类型,右操作数具有算术类型
  • 左操作数具有与右操作数类型兼容的结构或联合类型的原子、限定或非限定版本
  • 左操作数具有原子指针类型、限定指针类型或非限定指针类型,并且(考虑左值之后左操作数的类型) 转换)两个操作数都是合格或不合格的指针 兼容类型的版本,左侧指向的类型 右边所指类型的所有限定符
  • 左操作数具有原子指针类型、限定指针类型或非限定指针类型,并且(考虑左值之后左操作数的类型) 转换)一个操作数是指向对象类型的指针,另一个操作数是指向对象类型的指针 是指向
    void
    的限定或非限定版本的指针,以及 左侧指向的类型具有指向该类型的所有限定符 按权利行事
  • 左操作数是原子指针、限定指针或非限定指针,右操作数是空指针常量;或
  • 左侧操作数的类型为原子、限定或非限定
    \u Bool
    ,右侧为指针
它们都不匹配左侧的指针和右侧的
333
。§6.5.16.1/p1是一个约束,要求一致性实施在违反约束时产生诊断(§5.1.1.3/p1):

一致性实施应产生至少一个诊断结果 消息(以实现定义的方式标识),如果 预处理翻译单元或翻译单元包含 违反任何语法规则或约束,即使行为是 还显式指定为未定义或实现定义


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

@haccks程序的哪个部分调用未定义的行为?只要不取消对指针变量的引用,将随机值赋给指针变量是完全有效的。@5gon12eder;这部分:
printf(“c=%u,c+1=%u”,c,c+1)。你需要解释吗?@haccks没错,
%u
应该改为
%p
。然而,这与meet的问题无关,也不能解释程序为什么要编译。@JensGustedt;我承认我的评论有误导性,我把它删掉了。但我认为存在UB,尽管可执行文件无效。@davmac未定义行为包括“终止转换或执行”。
从技术上讲,您的代码没有问题。
-1。至少您的编译器应该发出警告:
[warning]格式“%u”要求参数类型为“unsigned int”,但是参数2的类型“char*”[-Wformat]
@haccks对gcc为true,但是其他一些编译器不检查
printf()
参数“从种族上讲没有什么错”——“从种族上讲”根本不是您在这里的意思。也许是“技术上的”。我一开始写的是“技术上的”,结果被否决了(虽然这是答案的一部分,但它没有说明为什么以及如何证明这段代码实际上违反了约束,因此每个C编译器都必须至少给出一个诊断,事实上OP承认它编译得不好,但给出了警告。