Путаница в отношении цели / поведения -Waggregate-return?

Глядя на Варианты предупреждений 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 классом — почему я не предупредил о «возвращенном агрегате» во втором примере?

8

Решение

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

5

Другие решения

Агрегаты определены в стандартах 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 ++ так сильно. Но я не могу подтвердить это никакими данными.

4

По вопросам рекламы [email protected]