为啥我可以链接两个库在 VC 中导出相同的 C-Function?

Posted

技术标签:

【中文标题】为啥我可以链接两个库在 VC 中导出相同的 C-Function?【英文标题】:Why can I link two libraries exporting the same C-Function in VC?为什么我可以链接两个库在 VC 中导出相同的 C-Function? 【发布时间】:2016-01-27 14:54:36 【问题描述】:

我有两个 C++ 库从共享代码中导出完全相同的 C 函数符号的情况。当我现在编译链接这两个库的可执行文件时,我没有收到来自 VC12 的任何链接器错误或警告。为什么是这样?它只是默默地选择了两个符号之一,我不知道选择了哪个。;​​

extern "C"  __declspec(dllexport) int function(void* argument);

有一个名为 /FORCE 的标志,即使有多个定义的符号,它也可以说服 VC 编译,但该标志没有设置。

我没有从微软那里找到任何官方信息,为什么这个链接根本不存在。我原以为会收到 LNK4006 警告,但我没有。

    我只是想知道这是预期的还是未定义的行为,这只是巧合而已。我读到了有关“单一定义规则”并未普遍应用于 C 代码的内容,但我找不到任何适用于 VC 编译器的可靠声明。 我可以假设,鉴于函数不使用任何单例,使用完全相同的代码和编译器标志,选择哪一个并不重要?

【问题讨论】:

因为您违反了 ODR 规则,这是未定义的行为。无需诊断。 允许 Visual Studio 向您发出警告。不幸的是,许多人禁用了该特定警告,因为当函数包含大量模板时会出现误报。 【参考方案1】:

您违反了单一定义规则。 你程序的行为是未定义的。

请参阅 C++ 标准中的“3.2 一个定义规则 [basic.def.odr]”部分。

    每个程序都应包含每个非内联函数的确切定义或在该程序中使用 odr 的变量;无需诊断。 ...

第 3.2.6 节描述了何时可以有多个定义 程序中的类类型、具有外部链接的内联函数等。


    我只是想知道这是预期的还是未定义的行为,这只是巧合而已。我读到了有关“单一定义规则”并未普遍应用于 C 代码的内容,但我找不到任何适用于 VC 编译器的可靠声明。
这是未定义的行为。 C++ 标准是主要标准,而不是 VC 编译器。
    我可以假设,鉴于函数不使用任何单例,使用完全相同的代码和编译器标志,选择哪一个并不重要?
这仍然是未定义的行为 - 尽管程序可能看起来像预期的那样运行。

【讨论】:

以上是关于为啥我可以链接两个库在 VC 中导出相同的 C-Function?的主要内容,如果未能解决你的问题,请参考以下文章

为啥不能在 TypeScript 中导出类实例?

如何从phpmyadmin中的数据库中的特定表中导出特定列

为啥值没有从报告中导出 - Access 2007

为啥 glGetAttribLocation 为两个不同的属性返回相同的值?

如何以与 toad 相同的方式在 PL/SQL 中导出数据库对象?

为啥使用microsoft visual studio2008时反应缓慢?????????????? 急!!!!!!!!!!