C C++函数名称冲突和崩溃不一致

C C++ Function name conflicts and crash inconsistency

本文关键字:崩溃 不一致 冲突 C++ 函数      更新时间:2023-10-16

有人能解释一下这个用户错误导致不一致崩溃的幕后原因吗。

这是的主要功能

#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内部的Bar()。C而不是我自己定义的Bar()
当然,修复是为了静态我自己的函数或更改我自己的Bar()函数的名称。

我知道写这样的代码杂乱无章,很容易出现这样的错误。有人能向我解释一下为什么代码会不一致地崩溃吗?

谢谢大家

问候

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

为了防止这个问题,使用匿名名称空间,如下所示:

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

在你的情况下,在任一foo中都这样做。C或main就可以了。等效地,您可以添加static:

static int Bar() {}

如果你用C.写作

使用匿名名称空间或static关键字使函数成为翻译单元的本地函数,因此链接器不会将其视为外部符号。通过这种方式,您可以在不同的翻译单位中拥有任意数量的具有相同签名的函数。

我认为您使用的是foo定义的Bar函数,因为在定义自己的Bar函数之前,它是通过foo.h包含的。

我很惊讶你的编译器没有警告你重复的定义(非法),但如果您定义了在#include"foo.h"之前的条形函数错误应该有被抛出。

此URL表示重新定义内联是非法的除非内联相同:

C静态内联函数重新定义规则

我的编译器在这方面抛出了一个错误。最好的避免方法是使用单独的命名空间或宏保护。。