为什么根据标题顺序获取C++编译警告

问题描述:

我正在使用编译标志-Wall -Wextra和-Werror。我在编译以下文件时遇到了“声明为'静态'的泛洪,但从未定义过[-Werror = unused-function]”警告(视为错误)。当我颠倒#include指令的顺序时没有这样的警告。请帮我理解为什么?为什么根据标题顺序获取C++编译警告

我知道我可以删除额外的警告和错误,并让我的程序编译,显然这不是我的意图,或者我的代码会更有趣。我试图获得C++的更深层次的知识,并通过清理代码中的警告来改善我的习惯。

我知道argp实际上是一个C库,而iostream是一个C++库,也许这是问题的一部分。我很乐意使用一个合适的C++库来完成argp的功能,但是我找不到一个。如果有一个我很乐意听到它。

#include <argp.h> 
#include <iostream> 

int main(int argc, char **argv) 
{ 
    return 0; 
} 

需要明确的是,我工作的一个重要的程序,并有希望用C++而不是C.我归结在这里展示给尽可能少的代码,该代码产生的具体原因我试图理解的效果。请不要暗示我不需要一个或另一个标题。

编译器:GCC

:~/scratch/argp_example$ gcc --version 
gcc (Ubuntu 5.2.1-23ubuntu1~12.04) 5.2.1 20151031 Copyright (C) 2015 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

编译invokation: g++ -o obj/main.o -c src/main.cpp -Wall -Wextra -Werror -pedantic -MMD --std=c++11 -Iinc

编译器特有的反馈:

In file included from /usr/include/x86_64-linux-gnu/c++/5/bits/gthr.h:148:0, 
       from /usr/include/c++/5/ext/atomicity.h:35, 
       from /usr/include/c++/5/bits/ios_base.h:39, 
       from /usr/include/c++/5/ios:42, 
       from /usr/include/c++/5/ostream:38, 
       from /usr/include/c++/5/iostream:39, 
       from src/main.cpp:2: 
/usr/include/x86_64-linux-gnu/c++/5/bits/gthr-default.h:101:1: warning: ‘int __gthrw_pthread_once(pthread_once_t*, void (*)())’ declared ‘static’ but never defined [-Wunused-function] __gthrw(pthread_once)^

有来自gthr.h.很多很多类似的错误这个特定的复制/粘贴来自没有错误的运行,但这是唯一的区别。

SOLUTION: 这是我选择的解决方案,但当然,您可以简单地颠倒包含的顺序。这是一个公认的错误,所以没有“正确的”答案,所有的解决方案都是解决方法。我认为,这个最不可能在稍后给我或其他人。

#include <argp.h> 
#undef __attributes__ 
#include <iostream> 
... 
+0

这是一个奇怪的问题。也许你可以将解析限制在一个单独的模块中,并且*不包括那个iostream? – wallyk

+0

看起来是一个给定的GNU错误:http://*.com/questions/7969419/nvcc-cuda-3-1-ghtr-default-h-flood-of-declared-static-but-not-defined- warnin –

+0

至于替补,你检查了[Boost.Program_options](http://www.boost.org/doc/libs/1_60_0/doc/html/program_options.html)吗? –

这是一个known bug。罪魁祸首是这个块的代码argp.h,当您使用-std=c++xx这是触发:

#ifndef __attribute__ 
/* This feature is available in gcc versions 2.5 and later. */ 
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ 
# define __attribute__(Spec) /* empty */ 
# endif 

有争议的声明通常标有__attribute__ ((__weakref__("pthread_meow"))),但这个宏引起的属性蒸发。

在错误得到解决之前,您可能需要使用-std=gnu++xx进行编译,或者在包含argp.h后手动编译#undef __attribute__

+0

你能否建议如何最好地搜索这样的已知错误?教一个人去钓鱼...?我没有在谷歌上运气。 – Jfevold

+0

@Jfevold嗯,我首先找出是什么原因造成的,然后搜索它是否是已知问题。使用'g ++ -E'来预处理这两个版本的代码,检查有什么不同('__attribute__((__weakref __(“...”)))''不见了),然后检查是什么导致它(argp.h定义了一个' __attribute__'宏),然后谷歌,看看这是一个已知的问题(这是'argp.h __attribute__'的最高结果之一。 –