为什么这个执行无效指针初始化的程序可以在C语言中正常编译? [英] Why this program that performs invalid pointer initialization compiles fine in C?

查看:99
本文介绍了为什么这个执行无效指针初始化的程序可以在C语言中正常编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个简单的C程序,希望它在编译时会失败,但是不幸的是,它可以在C中编译并运行良好,但在C ++中却无法编译. 考虑下面的程序:

I wrote a simple C program and I was expecting that it will fail in compilation but unfortunately it compiles and runs fine in C, but fails in compilation in C++. Consider below program:

#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扩展名保存了该程序,但在此编译器上编译失败.

I think that this program definitely can't compile in C++ due to C++'s strong type checking. Why this program compiles in C? It is the fact that compiler shows warnings also. I am using Orwell Dev C++ IDE(gcc 4.8.1 compiler). I also tried same program on other compiler (Borland Turbo C++ 4.5) , saved it by extension .c and on this compiler it failed to compile.

推荐答案

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

This code is neither legal C nor legal C++.

N1570§6.7.9/p11:

N1570 §6.7.9/p11:

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

The initializer for a scalar shall be a single expression, optionally enclosed in braces. The initial value of the object is that of the expression (after conversion); the same type constraints and conversions as for simple assignment apply, taking the type of the scalar to be the unqualified version of its declared type.

第6.5.16.1/p1节提供了简单分配的条件:

§6.5.16.1/p1 provides that for simple assignment:

应满足以下条件之一:

One of the following shall hold:

  • 左操作数具有原子,合格或不合格的算术类型,而右操作数具有算术类型;
  • 左操作数具有与右类型兼容的结构或联合类型的原子,合格或不合格版本;
  • 左操作数具有原子,限定或不限定的指针类型,并且(考虑到左操作数在左值之后将具有的类型 转换)两个操作数都是指向合格或不合格的指针 兼容类型的版本,并且左侧指向的类型具有 右边所指类型的所有限定词;
  • 左操作数具有原子,限定或不限定的指针类型,并且(考虑到左操作数在左值之后将具有的类型 转换)一个操作数是一个指向对象类型的指针,另一个 是void的合格或不合格版本的指针,并且 左侧指向的类型具有指向该类型的所有限定符 到右边;
  • 左边的操作数是原子的,限定的或不合格的指针,右边的是空指针常量;或
  • 左边的操作数的类型是atomic,qualified或unqualified _Bool,右边的是指针.
  • the left operand has atomic, qualified, or unqualified arithmetic type, and the right has arithmetic type;
  • the left operand has an atomic, qualified, or unqualified version of a structure or union type compatible with the type of the right;
  • the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
  • the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) one operand is a pointer to an object type, and the other is a pointer to a qualified or unqualified version of void, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
  • the left operand is an atomic, qualified, or unqualified pointer, and the right is a null pointer constant; or
  • the left operand has type atomic, qualified, or unqualified _Bool, and the right is a pointer.

没有一个与左侧的指针匹配,而与右侧的333匹配. §6.5.16.1/p1是 constraint ,并且需要符合规范的实现才能在出现约束违规时产生诊断信息(§5.1.1.3/p1):

None of which matches a pointer on the left and 333 on the right. §6.5.16.1/p1 is a constraint, and conforming implementations are required to produce a diagnostic upon a constraint violation (§5.1.1.3/p1):

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

A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined.

碰巧,GCC决定在C模式下发出警告而不是错误并继续进行编译,但这不是必须的.

It happens that GCC decides to produce a warning instead of an error in C mode and continue to compile it, but it doesn't have to.

这篇关于为什么这个执行无效指针初始化的程序可以在C语言中正常编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆