全局const char上的错误LNK1169 *

时间:2012-12-07 22:44:14

标签: c++ visual-studio-2010 visual-c++

我在使用Visual Studio 2010和C ++时遇到了一些奇怪的行为。 我有一个头文件,我在其中声明了一些全局常量

#ifndef CONSTANTS_H
#define CONSTANTS_H

#define WIN32_LEAN_AND_MEAN

// Macros...
#define SAFE_RELEASE(ptr) { if (ptr) { ptr->Release(); ptr = NULL } }
#define SAFE_DELETE(ptr) { if (ptr) { delete ptr; ptr = NULL; } }

// Constants...
const char* CLASS_NAME = "WinMain";
const char GAME_TITLE[] = "DirectX Window";

const int GAME_WIDTH = 640;
const int GAME_HEIGHT = 480;

#endif

我的问题来自以下一行:

const char* CLASS_NAME = "WinMain";

当它是这样的,我构建我的解决方案时,我得到以下2个错误:

error LNK1169: one or more multiply defined symbols found

error LNK2005: "char const * const CLASS_NAME" (?CLASS_NAME@@3PBDB) already defined in graphics.obj

现在很奇怪,因为一个'在文件中查找'并且我绝对不会在其他地方声明它,即没有重复的声明。

我应该将其更改为:

const char* const CLASS_NAME = "WinMain";

OR

const char CLASS_NAME[] = "WinMain";

编译得很好!但据我所知char* x相当于char x[],而且我对指针和指向值强制执行'const-ness'的事实应该没有区别......或者是吗?

我对Windows平台上的C ++开发有点新意,所以非常感谢任何帮助!

3 个答案:

答案 0 :(得分:6)

您错误的是您没有将常量声明为常量。在C ++语法(以及C语言)中,为了声明一个常量指针,你必须这样做

const char* const CLASS_NAME = "WinMain";

请注意,您的GAME_TITLEGAME_WIDTHGAME_HEIGHT已正确声明为常量,这就是为什么它们不会给您带来任何麻烦。只有CLASS_NAME声明不正确,即非常数。

默认情况下,C ++中的常量具有内部链接,这就是为什么你可以在头文件中定义它们而不违反一个定义规则。

答案 1 :(得分:5)

不要在标头中定义变量。当您在多个翻译单元中包含该标题时,您将拥有该定义的多个副本。

只有在那里声明变量(使用extern),并在一个翻译单元中定义它们。

那说......对于内置类型的常量,可以对此规则进行例外处理,因为它们默认具有内部链接。

也就是说,这两个程序在功能上完全相同:

const int x = 42;
int main() {}

static const int x = 42;
int main() {}

这确保为每个翻译单元生成一个副本,完全避免此问题。

认为对于数组也是如此。所以,当然,const它会把你自己打倒。


  

但据我所知'char * x'相当于'char x []',

仅在功能参数列表中。在完全成熟的声明中,x将采用从初始化程序确定的维度的数组类型。

答案 2 :(得分:1)

您收到错误,因为如果您将文件包含在多个编译单元中,则在每个单元中声明该名称的变量。编译不是问题,但是当链接器尝试链接时,会看到同一变量的多个定义。您可以使用const int变量和const char GAME_TITLE[]来解决此问题,因为它们具有静态链接,但对于字符串文字(基本上是char数组),您将收到此错误。您应该能够使用extern

解决问题