C++ C++;名称空间在Windows和linux中的行为不同?

C++ C++;名称空间在Windows和linux中的行为不同?,c++,linux,unix,visual-studio-2017,namespaces,C++,Linux,Unix,Visual Studio 2017,Namespaces,所以我有一个dll,我在其中使用了两个typedef,包装在一个名称空间中,就像这样 常数.h namespace constants { typedef int Integer; typedef float Decimal; } 现在,在dll中使用它的地方,我使用了名称空间,而没有使用完全限定的名称,比如使用名称空间常量 现在有一个文件处理程序.h正在导入另一个实用程序.h,该实用程序反过来导入这个常量.h utility.h(与constants.h相同的dll) han

所以我有一个dll,我在其中使用了两个typedef,包装在一个名称空间中,就像这样

常数.h

namespace constants
{
    typedef int Integer;
    typedef float Decimal;
}
现在,在dll中使用它的地方,我使用了名称空间,而没有使用完全限定的名称,比如
使用名称空间常量

现在有一个文件处理程序.h正在导入另一个实用程序.h,该实用程序反过来导入这个常量.h

utility.h(与constants.h相同的dll)

handler.h(另一个dll)

这里的common.h具有为另一个数据类型定义的相同整数和十进制typedef

据我所知,当我们使用
名称空间常量时
typedefs作用域将仅在该转换单元内,即这里的utility.h

因此,common.h中定义的typedef并没有弄乱utility.h中的常量typedef,因为它们被包装在名称空间下

common.h(第三个dll)

这在VisualStudio中运行良好,并且成功地构建了二进制文件

然而,在Linux上,我得到了

 error: reference to 'Integer' is ambiguous
为什么相同的代码在Linux而不是windows中给出编译器错误

我使用的是Microsoft visual studio 2017

注意:我知道这样一个事实,即我们应该始终使用带有完全限定名的名称空间。但我只想知道为什么win/unix中的行为不同

据我所知,当我们使用名称空间常量时,typedefs作用域将仅位于该转换单元内,即这里的utility.h

h本身不是一个“平移单位”。如果将utility.h包含到另一个文件中,则该另一个文件(及其所有包含的文件)是一个翻译单元

例如,在预处理器处理了include指令之后,handler.h(在其翻译单元内)的内容将是:

namespace constants
{
    typedef int Integer;
    typedef float Decimal;
}
using namespace constants;
typedef unsigned long int Integer
这是一个潜在的问题,因为非限定类型名
Integer
将是不明确的

为什么相同的代码在Linux中出现编译器错误

您尚未实际演示如何使用
整数
,因此我们无法确认。但是,如果编译器是正确的,那么您是在含糊不清地引用
整数
,这会导致程序格式错误


但同样的事情在VisualStudio上也可以正常工作


如果使用<代码>整数< /C> >的假设是正确的,如果编译器不发出诊断消息,编译器不符合C++标准。Win和Linux之间没有区别。你能创建一个翻译单元吗?听起来你对什么是“翻译单元”感到困惑。如果一个头文件包含在两个源文件中,那么它的代码将成为两个翻译单元的一部分。但是使用头中的namespace

指令的文件作用域
会影响源文件的其余部分,是的。我向您保证,这里的编译器/平台之间没有区别。这听起来像是将各种概念(特别是DLL)混为一谈,而没有认识到源代码更改在哪里造成了差异。试着组合一个MCVE。要扩展@Sneftel关于的评论,基本上编译器不知道“源文件”或“头文件”。它真正了解的是当前的翻译单元(基本上是一个包含所有头文件的源文件)。它对其他可能的翻译单位一无所知。链接器的任务是将不同的编译翻译单元(现在由编译器生成的对象文件)放在一个可执行文件中,但同样的事情在VisualStudio上也可以正常工作
typedef unsigned long int Integer
 error: reference to 'Integer' is ambiguous
namespace constants
{
    typedef int Integer;
    typedef float Decimal;
}
using namespace constants;
typedef unsigned long int Integer