NRVO против раннего возврата для типов, не использующих семантику перемещения (GCC 14 -Wnrvo)C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 NRVO против раннего возврата для типов, не использующих семантику перемещения (GCC 14 -Wnrvo)

Сообщение Anonymous »

GCC 14 представил новый флаг -Wnrvo:

Новое предупреждение -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;
}
Этот код помечается новым предупреждением GCC:

Код: Выделить всё

./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;
}
Не совсем удовлетворен, поскольку решение, ИМХО, менее читабельно, я решил протестировать его, чтобы увидеть, в чем будет выгода, используя fast-bench.com.
Оказывается, что с -O3 версия с ранним возвратом работает в 3,8 раза быстрее, чем версия NRVO.
Вопросы:
  • Вводит ли предупреждение GCC в данном случае в заблуждение? Имеет ли смысл целенаправленно избегать NRVO в ситуациях, когда возможно досрочное возвращение?
  • Почему версия NRVO настолько медленнее? Есть ли ошибка в моем тесте? Есть ли способ переписать функцию, чтобы она поддерживала NRVO и не была менее эффективной, чем исходная?


Подробнее здесь: https://stackoverflow.com/questions/784 ... cc-14-wnrv
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»