Защо получавам предупреждения за компилиране на c++ в зависимост от реда на заглавките

Използвам флагове за компилиране -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 предвид това: 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++, но нямам конкретна причина да вярвам, че не е грешка и в 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
Бихте ли посъветвали как най-добре да търсите известни грешки като този? Да научи човек да лови риба...? Нямах късмет с Google. - person Jfevold; 01.05.2016
comment
@Jfevold Е, първо разбрах какво го причинява и след това потърсих дали е известен проблем. Използвайте g++ -E, за да обработите предварително и двете версии на кода, проверете какво е различно (__attribute__ ((__weakref__("..."))) го няма), след това проверете какво го причинява (argp.h, дефиниращ макрос __attribute__), след това Google, за да видите дали това е известен проблем (той е сред най-добрите резултати за argp.h __attribute__. - person T.C.; 01.05.2016