Глядя на Варианты предупреждений GCC, Я наткнулся -Waggregate обратный.
-Waggregate обратный
Предупреждать, если какие-либо функции, которые возвращают структуры или объединения, определены или вызваны. (В языках, где вы можете вернуть массив, это также вызывает предупреждение.)
Небольшой пример, который вызывает предупреждение:
class foo{};
foo f(void){return foo{};}
int main(){}
$ g ++ -std = c ++ 0x -Waggregate-return -o main main.cpp
main.cpp: в функции ‘foo f ()’:
main.cpp: 2: 5: предупреждение: функция возвращает агрегат [-Waggregate-return]
еще один небольшой пример, который не вызывает предупреждение:
#include <string>
std::string f(void){return "test";}
int main(){}
Какая выгода от использования -Waggregate-return?
Почему кто-то хочет быть предупрежден об этом?
Кроме того, не является ли std :: string классом — почему я не предупредил о «возвращенном агрегате» во втором примере?
Следуя комментариям, сделанным @AlokSave, вот более позднее редактирование ответа:
Три являются двумя возможными объяснениями этого флага компилятора. Так как документации по этому вопросу немного, неясно, каково его первоначальное значение, но есть, в основном, два возможных объяснения:
1) Предупреждение пользователя о возврате агрегатного объекта заставляет его знать, что стек может переполниться, если агрегатный объект (который расположен в стеке) возвращается.
2) Судя по всему, какой-то старый компилятор C не поддерживал возврат аггрегатов (нужно было возвращать указатель).
Какой из двух является лучшим, мне трудно судить. Однако более релевантную информацию об этом флаге можно найти по следующим ссылкам:
http://bytes.com/topic/c/answers/644271-aggregate-return-warnings
https://lists.gnu.org/archive/html/bug-gnulib/2012-09/msg00006.html
Цитирую по последней ссылке:
В приложениях GNU, с которыми я знаком (Emacs, coreutils, …)
мы просто отключаем -Waggregate-return. Это полностью
анахроничное предупреждение, так как его мотивация заключалась в
поддерживать обратную совместимость с компиляторами C, которые
не разрешать возвращать структуры. Эти компиляторы
давно умерли и больше не имеют практического значения.
Агрегаты определены в стандартах C и C ++. Версия C говорит (C99 6.2.5 Types / 20-21):
Тип структуры описывает последовательно размещенный непустой набор объектов-членов
[…]
(и, при определенных обстоятельствах, неполный массив), каждый из которых имеет
указанное имя и, возможно, отдельный тип.Арифметические типы и типы указателей вместе называются скалярными типами. Массив и
Типы структуры в совокупности называются агрегатными типами.
Версия C ++ гласит (N3485 8.5.1 [dcl.init.aggr] / 1):
Агрегат — это массив или класс (раздел 9) без предоставленных пользователем конструкторов (12.1), без инициализаторов скобок или равных для нестатических элементов данных (9.2), без закрытых или защищенных нестатических элементов данных ( Пункт 11), нет базовых классов (пункт 10) и нет виртуальных функций (10.3).
Ваш второй пример (с std::string
) не вызывает предупреждение, потому что std::string
имеет предоставленный пользователем конструктор; и имеет личные данные членов.
Я подозреваю, что это предупреждение существует, потому что считается плохим стилем для возврата агрегата в C; Передача указателя выхода предпочтительнее на этом языке. Я не думаю, что это относится к C ++ так сильно. Но я не могу подтвердить это никакими данными.