2012-07-13 77 views
3

有人可以解释幕后导致此用户错误不一致崩溃的原因。C C++函数名称冲突和崩溃不一致

这里的主要功能是

#include "foo.h" 
inline int Bar(const int &a) 
{ 
... 
} 
... 
int b=Bar(a); 

在 “foo.c的” 也有功能

inline int Bar(const int &a) 

副本这是问题所在。我不拥有foo.h也不拥有foo.C,并且在foo.h中没有Bar(int)的声明。 所有编译和工作正常与旧版本的foo.h和foo.C
在我的同事更新他的foo.C中的一些其他功能后,代码仍编译好,但它开始崩溃执行。
通过ddd进行调试表明,当我的主函数调用Bar()时,它实际上调用了foo.C中的Bar()而不是我自己定义的Bar()。
因为修复是静态我自己的功能或更改我自己的Bar()函数的名称。

我知道写这样的代码是混乱的,并且很容易出现这样的错误。有人可以向我解释为什么代码崩溃不一致?

谢谢大家

问候

+2

是有一些原因,你不能只命名函数别的东西吗?的 – Wug 2012-07-13 20:41:35

+1

可能重复[它是一个未定义的行为有一个内联函数的定义不同?(http://stackoverflow.com/questions/11200805/is-it-an-undefined-behavior-to-have-different-definitions内联函数) – 2012-07-13 21:19:18

+0

这个问题有点混乱,因为标题中显示“C”,而你的文件是“foo.c”(而不是“foo.cxx”或“foo.cpp”),但你显然是用C++编写的(参考文献)。无论如何,这违反7.1.2(4)。 – 2012-07-13 21:21:40

回答

2

内联函数还有外部链接。也就是说,它们被编译器发送到相应的目标文件中,并且当链接器链接应用程序时,它认为具有相同签名(包括它们的名称和封装名称空间)的所有函数都是相同的。由于该函数被定义为inline,它随机选择一个定义并删除另一个,而不会出错。 (这是违反了一个定义规则,根据标准导致未定义的行为。)

为了避免这个问题使用匿名命名空间,就像这样:

namespace { 
inline int Bar(const int &a) 
{ 
... 
} 
} 

在你的情况下这样做无论是foo.C还是main都可以做到这一点。等效您可以添加static

static int Bar() {} 

如果你在C.

编写使用匿名命名空间或static关键字使功能本地的翻译单元,所以链接器并不把它看成一个外部符号。这样,您可以在不同的翻译单元中拥有相同签名的任意数量的函数。

+0

谢谢大家的解释。 – elgnoh 2012-07-13 21:58:12

0

我想你使用的是foo定义的Bar函数,因为它是在定义你自己的Bar函数之前通过foo.h #included。

我很惊讶你的编译器不会警告你的 重复定义(非法的),但如果你已经确定你的#include之前 酒吧功能“foo.h中”错误应该有 被抛出。

该URL说内嵌的重新定义是非法的,除非 内联是一样的:

C static inline function redefinition rules

我的编译器在此抛出一个错误。避免最好的方法是使用一个单独的命名空间或宏卫..