【发布时间】:2020-03-11 10:41:01
【问题描述】:
我正在编写用于测试的代码,其中我有一个TestUtil.h,它定义了两个常量和一些函数。我将此头文件实现为TestUtil.cpp,还有第三个文件ActualTests.cpp,我正在其中编写实际测试。 TestUtil.h 和 TestUtil.cpp 只是编写简洁测试的帮助文件。
我有嵌套的命名空间,TestUtil.h 看起来像这样:
namespace SNMPSubAgentTesting {
namespace MibDataReaderTesting {
const wchar_t* TEST_MUTEX_NAME = L"TestMutex";
const wchar_t* TEST_MEMORY_NAME = L"TestMemory";
//some functions
}
}
在实现TestUtil.cpp我包含上面的头文件并给出实现:
#include "TestUtil.h"
namespace SNMPSubAgentTesting {
namespace MibDataReaderTesting {
//implementations
}
}
在第三个文件ActualTests.cpp 中,我再次包含TestUtil.h 以便使用实用功能:
#include "TestUtil.h"
namespace SNMPSubAgentTesting {
namespace MibDataReaderTesting {
//Test class and tests
}
}
编译器给出一个链接错误,并指出TestUtil.h 中的两个const 变量已在TestUtil.cpp 中定义,因此无法编译ActualTests.cpp。由于const 变量是内部链接的,我们可以在多个文件中包含包含const 变量的标头而不会出现链接错误,为什么在我的情况下它没有链接?是因为嵌套的命名空间吗?
编辑:我正在使用 Microsoft 单元测试框架进行测试。 const 变量在 MibDataReaderTesting 命名空间中,而不是在全局命名空间中。
我的源代码中有头文件,这些头文件包含在多个文件中,并且其中包含 const 变量。在这种情况下没有错误,但对于测试用例它给出了错误。黑白源代码和测试代码的唯一区别是测试框架和嵌套命名空间
【问题讨论】:
-
您正在标题中的全局命名空间中定义对象。它们将在任何将它们拉入的翻译单元中按原样定义。它们是
const是无关紧要的。一种适当的解决方案是在标题 没有 指定初始值的情况下extern它们,然后将它们的实际定义放入具有初始值的 one 翻译单元中(因为它们是常量,永久)值。 -
@WhozCraig 但是在命名空间范围内声明的名称应该具有内部链接,如果它们是“...非易失性非模板(C++14 起)非内联(C++17 起)非导出(C++20 起)const 限定变量(包括 constexpr),未声明
extern且之前未声明为具有外部链接”(强调我的)。这些变量在命名空间范围内,是 const 限定的,并且没有被声明为extern并且之前没有被声明为具有外部链接。 (引自en.cppreference.com/w/cpp/language/…)。 -
@WhozCraig 但变量是在
MibDataReaderTesting命名空间内定义的。它们在全局命名空间中的情况如何? -
什么是编译器以及你编译的 C++ 版本是什么?
-
@MahanGM 这是 Visual Studio 中的 Visual C++ 和最新的 Windows SDK
标签: c++ visual-c++ namespaces constants linker-errors