clang报“redefinition of”错误时,实际会明确指出具体符号名(如'redefinition of 'foo'),模糊提示通常因日志截断或ide隐藏所致;根本原因多为头文件缺乏防护、全局变量重复定义、非inline函数多处实现、宏重复定义、误将.h当.cpp添加,或与系统头文件中同名结构体冲突。

为什么Clang报redefinition of而不是更具体的错误名
Clang本身不直接输出redefinition of这种宽泛提示——它总是跟具体符号名,比如redefinition of 'foo'或redefinition of 'struct sched_attr'。如果你只看到模糊的“redefinition of”,大概率是编译日志被截断,或IDE(如Dev-C++、Keil)隐藏了后续内容。务必展开完整错误行,看清单引号里的那个名字,这才是关键线索。
头文件没加防护导致类/变量重复定义
这是最常见原因:一个头文件被多个源文件包含,而里面直接定义了变量、函数或类,没有防护机制。
- 检查出错符号是否出现在
.h文件里,且没用#ifndef/#define/#endif或#pragma once - 如果定义的是全局变量(如
int a = 1;),必须改成声明:extern int a;,再在某个.cpp里定义一次 - 类定义必须放在头文件里,但要加防护;类的成员函数实现不要写在头文件里(除非inline或模板)
- 宏定义重复也会触发该错误,比如两个头文件都写了
#define __LDREXW,得用#ifndef __LDREXW包住
多个源文件里都实现了同一个非inline函数
Clang链接阶段发现同一函数名在多个.o文件中都有定义,就会报redefinition of 'func_name'。
Clang 22.1.3 Windows 64 位历史版本安装包,适合旧项目兼容、LLVM/Clang 工具链回退、编译行为对比、链接问题复现和 C/C++ 构建环境维护。
- 确认该函数是不是在多个
.cpp里写了完整实现(函数体),而不是只在头文件里声明 - 如果是工具函数,统一放到一个
utils.cpp里实现,其他文件只#include "utils.h" - 想在头文件里放实现?加
inline关键字,或改用static(但会为每个翻译单元生成一份副本) - 检查是否误把
.h当成.cpp添加进了项目——Dev-C++里右键项目→“添加文件”时容易选错
系统头文件和用户代码冲突(比如struct sched_attr)
这类问题多见于Linux平台或嵌入式项目,glibc升级后自带某些结构体定义,而你的代码还手动写了同名结构体。
- 查清出错结构体是否属于系统API(如
sched_attr、atomic_t),运行grep -r "struct sched_attr" /usr/include/确认 - 优先删掉你代码里的重复定义,改用系统头文件:
#include <linux></linux> - 实在无法删除,用条件编译兜底:
#ifndef SCHED_ATTR_SIZE_VER0…#endif,这个宏由glibc 2.41+定义 - 注意:Clang默认包含路径比GCC略窄,有时需显式加
-I/usr/include/linux才能找到系统头
真正麻烦的不是语法层面的重复,而是符号在不同编译单元间隐式泄露——比如头文件里漏了extern,或忘了inline,或系统头版本跳变。盯住错误里单引号中的名字,顺藤摸瓜找定义位置,比盲目删代码靠谱得多。










