首页 > 解决方案 > -I 编译器选项如何导致不同的警告触发器?

问题描述

我最近的任务是重组一个应用程序并遇到了一个相当奇怪的问题。我已尽我所能将问题简化为示例代码。考虑以下:

罪犯.h

__attribute__ ((visibility ("default")))
typedef struct A {
    int a;
} A;

测试.cpp:

#include <iostream>

#include <offender.h>

int main(void)
{
    A a;
    a.a = 10;
    std::cout << a.a << "\n";
    return 0;
}

如果我运行:

g++ -Wall -Werror -o test -I. test.cpp
In file included from test.cpp:3:
./offender.h:4:3: error: ‘visibility’ attribute ignored [-Werror=attributes]
    4 | } A;
      |   ^
cc1plus: all warnings being treated as errors
make: *** [Makefile:3: all] Error 1

但是,如果我将 offender.h 移动到系统定义的路径中并在没有 -I 的情况下进行编译,这是有道理的。我明白了:

sudo mv offender.h /usr/local/include/
g++ -Wall -Werror -o test test.cpp

没有触发警告。

如果我从当前目录包含头文件,但如果我从预定义的包含目录中包含它,它怎么可能会发生警告?我错过了什么?

这已经使用 g++ 7.5.0 (Ubuntu 18.04) 和 9.3.0 (Ubuntu 20.04) 进行了测试,两者都生成相同的输出。

编辑:澄清问题

标签: c++g++compiler-warnings

解决方案


文件说_

声明操作系统和运行时库接口的头文件通常不能用严格符合的 C 语言编写。因此,GCC 对系统头文件中的代码进行特殊处理。在 GCC 处理系统标头时,所有警告,除了由 '#warning' 生成的警告(请参阅诊断)之外,都会被抑制。


推荐阅读