C C++函数名称冲突和崩溃不一致
C C++ Function name conflicts and crash inconsistency
有人能解释一下这个用户错误导致不一致崩溃的幕后原因吗。
这是的主要功能
#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静态内联函数重新定义规则
我的编译器在这方面抛出了一个错误。最好的避免方法是使用单独的命名空间或宏保护。。
- 大于65535的C++数组[size]引发不一致的溢出
- 在 C++(和 C)中进行类型转换时明显不一致
- 填充上编译器生成的复制构造函数之间的不一致
- 犰狳的 print() 方法和 cout 在从 Rcpp 调用时顺序不一致
- CreateDIBSection为同一图像返回不一致的位图位值
- 在 Qml 中从 QSqlTableModel 中删除单行时视图不一致
- 模板参数推导不一致
- 声明中不一致的no是否违反ODR?
- 如何删除分支因子不一致的树,最大为 30,40
- 从 C++ 函数与 Python 函数返回的不一致值用于偏斜正态分布
- 从 C 字符串构造 std::string 与从另一个 std::string 构造 std::string 不一致
- 这种比较是否不一致(或者存在其他问题)?
- 以下可变参数模板行为是否不一致?
- 如何修复我的链表读数不一致的问题?
- 在C++17中,为什么类模板和函数模板的指针类型推导明显不一致
- 在提升时不一致崩溃::线程::release_handle?
- NDK 问题:在 32 位上崩溃,在 64 位上不一致
- 由于不一致,无法跟踪崩溃
- std::push_back和insert(end(),x)之间的矢量不一致崩溃
- C C++函数名称冲突和崩溃不一致