Новое предупреждение -Wnrvo, чтобы предупредить, если именованное возвращаемое значение оптимизация не выполняется, хотя это разрешено [class.copy.elision]. Дополнительную информацию см. в руководстве.
Я решил посмотреть, какие предупреждения появятся, если я добавлю этот флаг в SFML 3.x, программу с открытым исходным кодом. мультимедийная библиотека, и появилось несколько предупреждений, все аналогично показанному здесь:
Код: Выделить всё
struct JoystickCaps
{
unsigned int buttonCount{};
std::array axes{}
};
// Early return version (original)
JoystickCaps JoystickImpl::getCapabilities() const
{
if (directInput)
return getCapabilitiesDInput(); // Joystick::ButtonCount)
caps.buttonCount = Joystick::ButtonCount;
// ...set more members in 'caps'...
return caps;
}
Код: Выделить всё
./SFML/src/SFML/Window/Win32/JoystickImpl.cpp:
In member function 'JoystickCaps JoystickImpl::getCapabilities() const':
./SFML/src/SFML/Window/Win32/JoystickImpl.cpp:342:12:
warning: not eliding copy on return in
'JoystickCaps JoystickImpl::getCapabilities() const' [-Wnrvo]
342 | return caps;
| ^~~~
Код: Выделить всё
// NRVO version
JoystickCaps JoystickImpl::getCapabilities() const
{
JoystickCaps caps;
if (directInput)
caps = getCapabilitiesDInput();
else
{
caps.buttonCount = m_caps.wNumButtons;
if (caps.buttonCount > Joystick::ButtonCount)
caps.buttonCount = Joystick::ButtonCount;
// ...set more members in 'caps'...
}
return caps;
}
Оказывается, что с -O3 версия с ранним возвратом работает в 3,8 раза быстрее, чем версия NRVO.
Вопросы:
- Вводит ли предупреждение GCC в данном случае в заблуждение? Имеет ли смысл целенаправленно избегать NRVO в ситуациях, когда возможно досрочное возвращение?
- Почему версия NRVO настолько медленнее? Есть ли ошибка в моем тесте? Есть ли способ переписать функцию, чтобы она поддерживала NRVO и не была менее эффективной, чем исходная?
Подробнее здесь: https://stackoverflow.com/questions/784 ... cc-14-wnrv