Почему я получаю предупреждения о компиляции С++ в зависимости от порядка заголовков

Я использую флаги компиляции -Wall, Wextra и Werror. Я получаю поток «объявленных« статических », но никогда не определенных [-Werror = unused-function] »предупреждений (рассматриваемых как ошибки) при компиляции следующего файла. Нет таких предупреждений, когда я меняю порядок директив #include. Пожалуйста, помогите мне понять, почему?

Я знаю, что мог бы удалить лишние предупреждения и ошибки и заставить мою программу скомпилироваться, но это явно не мое намерение, иначе мой код был бы более интересным. Я пытаюсь получить более глубокие знания о 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.

вызов компилятора: 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. Эта конкретная копия/вставка была из запуска без -Werror, но это единственное отличие.

РЕШЕНИЕ: Это был мой выбор решения, но, конечно, вы можете просто изменить порядок включений. Это признанная ошибка, поэтому нет «правильного» ответа, все решения будут обходными. Этот, я думаю, вряд ли вызовет раздражение у меня или у других позже.

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

person Jfevold    schedule 30.04.2016    source источник
comment
Это странная проблема. Возможно, вы можете ограничить синтаксический анализ одним модулем и не включать в него iostream?   -  person wallyk    schedule 01.05.2016
comment
Похоже, что это ошибка GNU, учитывая следующее: not-defined-warnin" title="nvcc cuda 3 1 ghtr default h наводнение объявленного статического, но не определенного предупреждения"> stackoverflow.com/questions/7969419/   -  person Andrew Henle    schedule 01.05.2016
comment
Что касается заменителей, проверили ли вы Boost.Program_options ?   -  person T.C.    schedule 01.05.2016
comment
@AndrewHenle Я читал это и признаю, что это аналогичная проблема, но я не вижу, где в этом вопросе говорится, что это ошибка GNU. В этом вопросе много особенностей аппаратного обеспечения и библиотек, которые не имеют отношения к моему вопросу, поэтому я подумал, что мог бы более эффективно получить ответ с более широким вопросом, поскольку мне было недостаточно его для понимания.   -  person Jfevold    schedule 01.05.2016
comment
Если вы пишете код C++, используйте компилятор C++, например g++, а не компилятор C, например gcc. Поскольку вы пишете код на C++, удалите тег c.   -  person user3629249    schedule 02.05.2016
comment
@ user3629249 gcc — это компилятор C++. G++ — это синтаксический сахар. Я посмотрю, является ли эта ошибка специфичной для С++, но у меня нет особых причин полагать, что это не ошибка в c.   -  person Jfevold    schedule 02.05.2016
comment
Если вы перейдете по ссылке на известную ошибку в принятом ответе, вы увидите, что это известная ошибка с параметрами компилятора --std=cxx (строка --std=c89 --std=c90 --std=c99)   -  person Jfevold    schedule 02.05.2016


Ответы (1)


Это известная ошибка. Виновником является этот фрагмент кода в 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 или вручную #undef __attribute__ после включения argp.h.

person T.C.    schedule 30.04.2016
comment
Не могли бы вы посоветовать, как лучше всего искать известные ошибки, подобные этой? Научить человека ловить рыбу...? Мне не повезло с гуглом. - person Jfevold; 01.05.2016
comment
@Jfevold Ну, я сначала понял, что вызывает это, а затем искал, известная ли это проблема. Используйте g++ -E для предварительной обработки обеих версий кода, проверьте, что отличается (__attribute__ ((__weakref__("..."))) исчез), затем проверьте, что вызывает это (argp.h, определяющий макрос __attribute__), затем погуглите, чтобы узнать, является ли это известной проблемой (это один из лучших результатов). для argp.h __attribute__. - person T.C.; 01.05.2016