You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C与C++全局变量声明定义差异:为何同代码编译结果不同

为什么C编译正常但C++出现多重定义错误?

先纠正术语理解

你对声明和定义的理解搞反了:

  • 声明:告诉编译器“这个名字(变量/函数)存在”,不分配内存,只是把名字引入当前作用域。
  • 定义:不仅声明名字,还为变量分配内存(或为函数提供实现),是实体的具体创建。

代码示例

main.c

#include <stdio.h>

int var; // 两种语言的处理差异核心点

int main()
{
    printf("%i\n", var);
    return 0;
}

sec.c

int var = 10;

C标准的处理规则

在C标准(比如C99、C11)里,int var;属于暂定定义(tentative definition):

  • 当一个翻译单元(比如main.c)里只有int var;,没有带初始化的显式定义时,编译器会把它当作弱定义。
  • 链接多个目标文件时,只要存在一个带初始化的显式定义(比如sec.c里的int var = 10;),所有的暂定定义都会被这个显式定义覆盖,不会触发多重定义错误。
  • 如果整个程序里都没有显式初始化的定义,暂定定义会自动被处理成int var = 0;的定义。

C++标准的处理规则

C++标准里没有“暂定定义”的概念:

  • int var;在C++中是带零初始化的强定义,会直接为变量分配内存,属于符合ODR(单一定义规则)的实体定义。
  • 链接时,main.c里的int var;和sec.c里的int var = 10;都是独立的强定义,违反了C++的单一定义规则,因此会抛出多重定义错误。

为什么extern可以解决问题?

不管是C还是C++,extern int var;都是纯声明,不会分配内存。把main.c里的int var;改成extern int var;后,main.c里只有对var的声明,整个程序里只有sec.c中的一个定义,完全符合两种语言的规则,所以链接可以正常通过。

内容的提问来源于stack exchange,提问作者Africa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 17:20:48