c - 如何避免全局常量的 "multiple definition"错误?

标签 c global-variables

我正在使用 Windows API 编写 C 程序。每个主要功能都有自己的文件,并且有一个用于原型(prototype)和包含等等的标题:

// Headers & global constants
#pragma once
#define _WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <WindowsX.h>
#include <Windef.h>

#define szClassName TEXT("EthicsPresentationWnd")
// Prototypes
LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK FontProc1(HWND hWnd, LPARAM lParam);
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);
ATOM RegisterWindow(HINSTANCE hInstance);

令我恼火的是 #define szClassName 行。我不喜欢使用宏,更愿意有一个合适的全局变量,wchar_t szClassName[],但如果我这样做,链接器会提示在包含头文件的每个模块中定义了多个变量。

我以为 #pragma once 指令会阻止这种情况,但事实并非如此。

这个问题有什么解决办法吗?

最佳答案

解决这个问题的方法是有一个单独的声明和定义......

header (*.h;抱歉,我不知道 WinAPI 类型名称,请根据需要进行调整):

extern const char szClassName[];

实现(*.c 或 *.cpp)

const char szClassName[] = "hello, world"

您看到问题是因为一个新符号 szClassName每次您的 *.c 或 *.cpp 文件之一包含 header 时都会被声明(即使有包含保护!);这会让链接器感到困惑(见下文)。

请注意,这将使 sizeof(szClassName)不再工作了。

进一步说明:

预处理后,编译器基本上是这样的:

  • 文件“a.c”:const char someSymbol[] = <some text, don't care what right now>;
  • 文件“b.c”:const char someSymbol[] = <some text, don't care if it's the same>;
  • 文件“抄送”:const char someSymbol[] = <some text, ditto>;

当链接器链接目标文件(例如,“a.obj”、“b.obj”和“c.obj”)时,它会看到用新值定义的相同符号(至少到链接器有关) --- 因此失败并出现错误。

关于c - 如何避免全局常量的 "multiple definition"错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24717066/

相关文章:

c++ - XDR 序列化可变长度字符串数组

javascript - 设置全局变量但未得到预期结果

global-variables - 使用 Hugo,如何从基本文件中定义的部分文件访问变量?

javascript - 将全局变量作为函数中的参数进行操作

c - Delphi 记录和 C 结构

c - 我怎么知道要重新分配多少内存?

c - 如何在C中打印队列[数据结构]?

c - struct_type[1] 是什么意思?

php - 全局变量不在 PHP 中的静态类方法中更新

C++:如何使数组可全局访问?