【发布时间】:2021-08-10 07:56:16
【问题描述】:
所以我有这个 dll,我使用两个 typedef 包装在这样的命名空间中,
Constants.h
namespace constants
{
typedef int Integer;
typedef float Decimal;
}
现在我在 dll 中使用它的地方,我使用了命名空间而不使用像 using namespace constants 这样的完全限定名称。
现在有一个文件 handler.h 正在导入另一个实用程序.h,而该实用程序又正在导入此常量 .h
utility.h(与 constants.h 相同的 dll)
#include "constants.h"
using namespace constants;
handler.h(另一个 dll)
#include "utility.h"
#include "common.h"
这里的 common.h 具有为另一种数据类型定义的相同 Integer 和 Decimal 类型定义。
据我所知,当我们使用using namespace constants 时,typedefs 范围将只在该翻译单元内,即这里的实用程序.h。
因此 common.h 中定义的 typedef 不会与 utility.h 中存在的常量 typedef 混淆,因为它们被包装在命名空间下。
common.h(第三个 dll)
typedef unsigned long int Integer
这在 Visual Studio 中运行良好,并且成功构建了二进制文件。
但是在 Linux 上我得到了
error: reference to 'Integer' is ambiguous
为什么相同的代码在 Linux 中会导致编译器错误,而在 windows 中却没有。
我使用的是 Microsoft Visual Studio 2017,
注意:我知道我们应该始终使用带有完全限定符名称的命名空间。但我只想知道为什么 win/unix 中的行为不同。
【问题讨论】:
-
using namespace ...在标题中通常是一个坏主意。 Win 和 Linux 没有区别。你能创建一个minimal reproducible example 吗? -
听起来您对“翻译单元”是什么感到困惑。如果一个头文件包含在两个源文件中,则其代码将成为两个翻译单元的一部分。
-
我不确定您所说的“命名空间常量”是什么意思。但是来自标头的文件范围
using namespace指令会影响源文件的其余部分,是的。 -
我向你保证,这里的编译器/平台之间没有区别。听起来您将各种概念(尤其是 DLL)混为一谈,而没有认识到源代码更改导致差异的原因。尝试组合一个 MCVE。
-
为了扩展@Sneftel 关于translation units 的评论,基本上编译器不知道“源文件”或“头文件”。它真正知道的只是当前的翻译单元(基本上是一个包含所有头文件的单个源文件)。它对其他可能的翻译单元一无所知。 linkers 的工作是将不同的编译翻译单元(现在由编译器生成的目标文件)放在一个可执行文件中。
标签: c++ linux unix visual-studio-2017 namespaces