【发布时间】:2013-04-30 12:41:30
【问题描述】:
这个问题与之前here 提出的问题密切相关。
为了让 Visual Studio 2010 C++ 调试器解析类内初始化的 const 变量,必须提供该变量的全局定义。
例如
这是类定义:
class B{
public:
static const int m_b=100;
};
这是成员的全局范围定义:
const int B::m_b;
如果没有全局定义,代码可以工作,但调试器无法在 B 的方法中看到 m_b。
但是,这会导致另一个问题。在非平凡的头文件包含安排(下面给出完整代码)中,Visual Studio 会产生此链接错误:
error LNK2005: "public: static int const B::m_b" (?m_b@B@@2HB) already defined in a.obj
1>a.exe : fatal error LNK1169: one or more multiply defined symbols found
但是 GCC 成功地编译、链接和运行代码。
这里是有问题的代码:
文件 a.cpp:
#include <iostream>
#include "a.h"
const int B::m_b;
int main()
{
B b;
std::cout << b.m_b;
return 0;
}
文件 a.h:
#pragma once
#include "b.h"
文件 b.cpp:
#include "b.h"
文件 b.h:
#pragma once
class B {
public:
static const int m_b = 100;
};
这里是链接器选项(默认 VS10 控制台程序):
/OUT:"a.exe"
/NOLOGO "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib"
/MANIFEST
/ManifestFile:"Debug\a.exe.intermediate.manifest"
/ALLOWISOLATION
/MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/DEBUG
/PDB:"Debug\a.pdb"
/PGD:"Debug\a.pgd"
/TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:QUEUE
这里是编译器选项(默认 VS10 控制台程序):
/ZI /nologo /W3 /WX- /Od /Oy- /D "_MBCS" /Gm /EHsc /RTC1 /GS /fp:precise /Zc:wchar_t
/Zc:forScope /Fp"Debug\sndbx.pch" /Fa"Debug\" /Fo"Debug\" /Fd"Debug\vc100.pdb" /Gd
/analyze- /errorReport:queue
同样,这可以使用 GCC ( g++ a.cpp b.cpp ) 成功构建、链接和运行。我提供的代码是完整的,因此可以复制、粘贴和运行。
【问题讨论】:
-
记住
#pragma once不是标准的。所以VS可能不支持它。导致包含多个头文件。 -
@Named VS 确实支持
#pragma once。 -
@Angew 是的,看来确实如此。 msdn.microsoft.com/en-us/library/4141z1cx.aspx
-
除了@Agnew 的评论,我还尝试了标准的“守卫”,以确保结果是一样的。
-
@MichaelBurr 谢谢,我现在已经更正了。
标签: c++ visual-studio gcc scope initialization