请问c具有像C ++的一个定义规则? [英] Does C have One Definition Rule like C++?

查看:126
本文介绍了请问c具有像C ++的一个定义规则?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


最近,我发现有一些情况是绝对违反C的ODR ++但在C编译器来编译确定。

Recently, I found out there are some cases that will absolutely violate the ODR of C++ but will be compiled OK in C compiler.

例如,这种怪异的情况下(与我):

For example, this wierd scenario (with me):

源1

int var_global=-3;

来源2

#include <stdio.h>
#include <conio.h>

unsigned int var_global;

int main() {    

 printf("%d \n",var_global);
 getch();
 return 0;

}

我有打印的结果是 -3 (即使在来源2 VAR_GLOBAL 无符号),并没有关于在重新定义 VAR_GLOBAL 。

I have the printed result is -3 (even though in Source 2 var_global is unsigned) and there is no error about the redefined of var_global.

我知道c具有不同的规则,C ++,但我不认为这就像如此不同。

I knew that C have different rules with C++ but I don't think it's so different like that.

我有谷歌,读了不少成果,但没有正式的结果这样的 C ++。

I have google and read a lot of results but there is no official result like this of C++.

所以问题是:

是否c具有像C ++的一个定义规则?

这是什么正式名称?

我需要它与C ++的规则相比较,这样我可以理解这两种语言更深。

I need it to compare with the rule of C++ so that I can understand both languages deeper.

P / S:我用Visual Studio 2010中编译上面的code

p/s: I used Visual Studio 2010 for compiling the code above.

推荐答案

我认为你在寻找什么是从 C11 标准章§6.2.7,兼容型和复合型的(重点煤矿的)

I think what you're looking for is chapter §6.2.7 from the C11 standard, Compatible type and composite type, (emphasis mine)

这是指在同一对象或函数应有的兼容所有类型声明;
  否则,行为是不确定的。

All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined.

和相关的兼容型,

两种类型具有兼容的类型,如果其类型是相同的。

Two types have compatible type if their types are the same.

在你的情况, INT unsigned int类型不兼容的类型。因此,未定义行为

In your case, int and unsigned int are not compatible types. Hence undefined behavior.

我想补充一点清晰的,在你的源2 unsigned int类型VAR_GLOBAL; 是一个声明,它不匹配其他declatation(和定义),因此,这是UB。

Just to add a bit of clarity, in your source 2, unsigned int var_global; is a declaration, and it does not match the other declatation (and definition), so, this is UB.

这是说,像一份声明

 printf("%d \n",var_global);

将始终考虑的参数%d个为类型 INT 。在案件的类型和格式说明不匹配,你会再次调用未定义行为

will always consider the argument to %d to be of type int. In case the type and the format specifier does not match, you'll again invoke undefined behavior.

编辑:

编辑后,答案是,使用 -fno常见来得到想要的错误。 (缺少的extern 是你与什么困扰,我相信的)。

After the edit, the answer is, use -fno-common to get the desired error. (missing extern is what you're bothered with, I believe).

从网上GCC手册引用,

Quoting from online GCC manual,

-fno常见

在C code,控制的未初始化的全局变量的位置。 Unix的C编译器传统上通过将变量公共块允许在不同的编译单元这些变量的多个定义。这是-fcommon指定的行为,是对大多数目标GCC默认值。在另一方面,不是由ISO C要求的行为,以及在一些目标可能携带速度或code大小点球上的变量引用。如果使用了-fno-common选项指定编译器应该放置在目标文件的数据段未初始化的全局变量,而不是生成它们作为公共块。 这样做,如果同一个变量被声明的影响(不的extern )在两个不同的汇编,你会得到一个多定义错误,当你将它们链接。在这种情况下,你必须使用-fcommon编译代替。与-fno-共同编制上,它提供了更好的性能,或者如果你想验证程序将始终把未初始化的变量声明这种方式与其他系统协同工作的目标是非常有用的。

In C code, controls the placement of uninitialized global variables. Unix C compilers have traditionally permitted multiple definitions of such variables in different compilation units by placing the variables in a common block. This is the behavior specified by -fcommon, and is the default for GCC on most targets. On the other hand, this behavior is not required by ISO C, and on some targets may carry a speed or code size penalty on variable references. The -fno-common option specifies that the compiler should place uninitialized global variables in the data section of the object file, rather than generating them as common blocks. This has the effect that if the same variable is declared (without extern) in two different compilations, you get a multiple-definition error when you link them. In this case, you must compile with -fcommon instead. Compiling with -fno-common is useful on targets for which it provides better performance, or if you wish to verify that the program will work on other systems that always treat uninitialized variable declarations this way.

我不知道C标准的措辞一个定义规则的任何提及,但沿线,你可以看看附件§J.5.11,多重外部定义的,


I don't know of any mention of the wordings "one definition rule" in the C standard, but along the line, you can look into annex §J.5.11, Multiple external definitions,

有可能是一个对象的标识符多个外部定义,或
  没有明确使用关键字的的extern ;如果定义不同意,或以上
  一个是初始化,该行为是不确定的。

There may be more than one external definition for the identifier of an object, with or without the explicit use of the keyword extern; if the definitions disagree, or more than one is initialized, the behavior is undefined.

这篇关于请问c具有像C ++的一个定义规则?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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