#c #gcc #g
#c #gcc #g
Вопрос:
Если у меня есть
namespace foo {
inline int bar() {
return 1119;
}
}
__attribute__((deprecated)) inline int bar() {
return 138;
}
в header.h
и
#include "header.h"
#include <iostream>
int main() {
int x = bar();
int y = foo::bar();
std::cout << x << std::endl;
std::cout << y << std::endl;
}
в source.cpp
, затем
g source.cpp -o deprecated-test
приводит к
source.cpp: In function ‘int main()’:
source.cpp:5:17: warning: ‘int bar()’ is deprecated [-Wdeprecated-declarations]
int x = bar();
^
In file included from source.cpp:1:
header.h:7:40: note: declared here
__attribute__((deprecated)) int bar() {
^~~
source.cpp:5:17: warning: ‘int bar()’ is deprecated [-Wdeprecated-declarations]
int x = bar();
^
In file included from source.cpp:1:
header.h:7:40: note: declared here
__attribute__((deprecated)) int bar() {
(в Ubuntu 18.10 с g 8.2.0).
Почему устаревшее предупреждение печатается дважды?
Отбрасываю некоторые предложения, которые были бы бесполезны:
-
[[deprecated]]
: Я знаю, что с C 14 вы можете использовать[[deprecated]]
атрибут, но мне нужно работать с C 11. -
Декларация против определения: документы, похоже, подразумевают, что его следует использовать с объявлением функции, а не с определением, но
- Мне нужно определить функции
inline
в заголовке, а не объявлять в заголовке и определять в исходных файлах; и - Попытка такого подхода все равно не остановила печать предупреждения дважды.
- Мне нужно определить функции
Комментарии:
1. Может быть ошибка. Clang не печатает два предупреждения.
[[deprecated]]
выдает те же результаты (два предупреждения в gcc, одно в clang).2. @tkausl спасибо, приятно знать! Поскольку clang не выводит предупреждение дважды, мне, возможно, придется попробовать и другие
g
версии, чтобы узнать, не является ли это недавно введенной и / или недавно исправленной ошибкой3. версии gcc до 5.5 даже печатают три предупреждения… Интересно. godbolt.org/z/383Hl0
4. @tkausl Вау… Кроме того, спасибо, что указали мне на godbolt.org ресурс. Я видел это раньше, но забыл об этом и не подумал заглянуть туда, чтобы попробовать другие компиляторы
5. @tkausl Похоже, что только gcc 5.x печатает 3 предупреждения. gcc 7.x печатает одно предупреждение, все остальные (которые я проверил) печатают два предупреждения. При использовании адреса устаревшей функции выводятся два предупреждения с помощью gcc 5.x и одно предупреждение для всех других версий.
Ответ №1:
Согласно документации GCC 8.2.0:
Устаревший атрибут выдает предупреждение, если функция используется где-либо в исходном файле. Это полезно при определении функций, которые, как ожидается, будут удалены в будущей версии программы. Предупреждение также включает в себя местоположение объявления устаревшей функции, чтобы пользователи могли легко найти дополнительную информацию о том, почему функция устарела, или что они должны делать вместо этого. Обратите внимание, что предупреждения появляются только для использования…
Должно быть только одно предупреждение, а не два. Итак, это ошибка в GCC.
Существует связанная ошибка для атрибутов типа (а не атрибутов функций) под названием: C / C __attribute__((deprecated))
, похоже, не переносит объявления, как подразумевается в документе.
Это было подтверждено как ошибка.
Комментарии:
1. Это, безусловно, ошибка в GCC, а не проблема с моим кодом, как упоминаете вы (и другие в комментариях к сообщению). Связанная ошибка, о которой вы упомянули, интересна, поскольку они не получают несколько предупреждений при одном использовании, а скорее предупреждения о объявлениях, которые не используются. Похоже, мне нужно будет отправить отдельный отчет об ошибке. Спасибо!