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

GCC 8.4.0下C与C++强符号、弱符号处理机制差异及链接报错问题咨询

Why Linking Fails for C++ Files But Works for C Files with Duplicate Global Variables?

Great question! The root cause lies in different handling of uninitialized global variables between C and C++ standards, which affects how the linker treats their symbols (strong vs. tentative/weak). Let's break this down step by step:

Background: Linker Symbol Rules

First, let's recap the rules you noted to set context:

  • Multiple strong symbols with the same name → Linker error (duplicate definition)
  • One strong symbol + one/multiple weak symbols → Linker picks the strong symbol
  • Only weak symbols with the same name → Linker picks one arbitrarily

What's the Difference Between C and C++ Here?

The key is how each language treats the line int gvar; (uninitialized global variable):

1. In C (.c files)

C has a concept called tentative definitions. A global variable declared without an initializer (like int gvar; in main.c) falls into this category. Here's what happens:

  • The linker merges all tentative definitions of the same variable into a single entry.
  • If there's an external definition (like int gvar = 111; in aux.c) with an explicit initializer, that becomes the authoritative definition, and all tentative definitions resolve to it.

So when compiling .c files, GCC treats main.c's gvar as a tentative definition, and aux.c's as a strong external definition. They merge cleanly without errors, and the final executable uses the value 111.

2. In C++ (.cpp files)

C++ does not recognize tentative definitions. Any global variable declaration without the extern keyword is a full, strong definition—even if it's uninitialized. Here's why:

  • int gvar; in C++ is implicitly zero-initialized. This counts as a complete definition that allocates storage for the variable, marking it as a strong symbol.
  • int gvar = 111; in aux.cpp is also a strong symbol (with an explicit initializer).

With two strong symbols named gvar, the linker hits the "multiple strong symbols" rule and throws the duplicate definition error you encountered.

How to Fix the C++ Case?

If you want the C++ code to link successfully, modify the declaration in main.cpp to a non-defining declaration using extern:

// main.cpp
#include <stdio.h>
extern int gvar; // Declare, don't define gvar
int main(){
    printf("shared var is %d\n",gvar);
    return 0;
}

Now only aux.cpp holds a strong definition of gvar, so the linker resolves the reference in main.cpp to it, and the program will output shared var is 111.

Note on GCC Version

Your GCC 8.4.0 behaves consistently with C and C++ standards here—this isn't a version-specific quirk, but a fundamental difference between the two languages.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 00:54:10