为何Clang++从-isystem目录引入头文件时忽略-fno-exceptions?
Clang++使用-isystem时忽略-fno-exceptions的原因分析
现象回顾
- 使用
clang++ -I lib -fno-exceptions编译时,因禁用异常的选项,会对头文件内的throw语句报错 - 改用
clang++ -isystem lib -fno-exceptions编译则成功,但程序运行时仍会抛出异常 - GCC在两种编译参数下都会因
throw语句触发编译错误
核心原因
Clang对系统头文件(通过-isystem指定目录下的文件)和用户头文件(-I指定目录下的文件)采用差异化的检查策略:
isystem标记的目录会被识别为系统头文件路径,Clang默认降低对系统头文件的检查严格度,其中就包括忽略-fno-exceptions选项对这类头文件内代码的限制。- Clang的设计逻辑是:系统头文件属于用户无法修改的第三方代码,通常被认为是符合标准的稳定实现,因此即使其中存在与当前编译选项冲突的代码(比如
throw语句),也会跳过检查以保证编译流程能完成。 - 而
-I指定的用户头文件,Clang会严格执行所有编译选项,所以-fno-exceptions会触发throw语句的报错。
GCC行为差异的原因
GCC对系统头文件和用户头文件的检查规则更统一,无论头文件来自-I还是-isystem目录,只要启用了-fno-exceptions,就会严格检查其中的throw语句并抛出编译错误,不会因为是系统头文件而放宽限制。
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

