Telegram Group & Telegram Channel
#creepy

Двуликий inline для функций

Так вышло, что сейчас в C++ ключевое слово inline для функций (точнее, само понятие inline-функции) наделяет их двумя абсолютно ортогональными друг другу effective смыслами. Понятно, что один смысл вытек из другого, но все равно это раздельные сущности. Это:

(1) [dcl.inline].2: Подсказка компилятору о том, что более предпочтительна подстановка кода из функции в место вызова, чем сам вызов функции. (В компиляторе Clang в LLVM IR этот атрибут у функции называется inlinehint)

(2) [dcl.inline].6: Правило, что у функции может быть несколько определений (definition) за программу. Для отсутствия UB это должны быть одинаковые определения - что естественным образом соблюдается, т.к. обычно метод определен в хидере. (В компиляторе атрибут у функции называется linkonce_odr)

Получается, что у функции есть два атрибута - inlinehint и linkonce.

Прикол в том, что:
Стандарт написан так, что inlinehint подразумевается только у функций, где явно написан спецификатор inline.

Clang выполняет именно это, т.е. inlinehint ставится тогда и только тогда, когда есть спецификатор inline.

То есть получается вот что: inline int random() { return 4; } будет И inlinehint, И linkonce.

А вот методы, которые по Стандарту являются implicit inline functions, например:
(*) инстанциации шаблонов
(*) default и deleted члены классов, и их неявные методы
(*) методы, чей definition находится внутри definition класса
(*) constexpr- и consteval-функции (на самом деле только constexpr, т.к. consteval "испаряется" и в LLVM IR его код тупо не попадает)

... они только linkonce. Надо все равно писать ключевое слово inline, чтобы было linkonce+inlinehint.

Если бы я мог редактировать стандарт, я бы переименовал inline functions в linkonce functions, потому что текущее описание в Стандарте сильно запутывает...

Интересные вопросы:
(1) Так ли сильно влияет наличие атрибута inlinehint на компиляцию? Я слышал, что компиляторы уже давно не обращают внимание на подобные подсказки...
Влияет практически незаметно. Порог для инлайнинга у обычного метода 225 попугаев, для inlinehint-метода 325 попугаев (ссылка на код), а для реальной разницы нужно ~1000 попугаев.

То есть в 99% кейсов inline constexpr void foo() и constexpr void foo() будут вести себя одинаково, однако в clang-tidy не принимают патч на удаление redundant inline, потому что остается какой-то непонятный 1% кейсов.

(2) Почему один атрибут вытекает из другого, если они ортогональны?
Чтобы компилятор мог в translation unit заинлайнить (inlinehint) функцию, TU нужно "видеть" исходник этой функции, то есть её тело. В общем случае это невозможно обеспечить, потому что если у нас N штук TU, то будет N определений одной и той же функции и линкер сломается. Поэтому эта функция должна являться linkonce, чтобы не нарушился ODR.



group-telegram.com/cxx95/37
Create:
Last Update:

#creepy

Двуликий inline для функций

Так вышло, что сейчас в C++ ключевое слово inline для функций (точнее, само понятие inline-функции) наделяет их двумя абсолютно ортогональными друг другу effective смыслами. Понятно, что один смысл вытек из другого, но все равно это раздельные сущности. Это:

(1) [dcl.inline].2: Подсказка компилятору о том, что более предпочтительна подстановка кода из функции в место вызова, чем сам вызов функции. (В компиляторе Clang в LLVM IR этот атрибут у функции называется inlinehint)

(2) [dcl.inline].6: Правило, что у функции может быть несколько определений (definition) за программу. Для отсутствия UB это должны быть одинаковые определения - что естественным образом соблюдается, т.к. обычно метод определен в хидере. (В компиляторе атрибут у функции называется linkonce_odr)

Получается, что у функции есть два атрибута - inlinehint и linkonce.

Прикол в том, что:
Стандарт написан так, что inlinehint подразумевается только у функций, где явно написан спецификатор inline.

Clang выполняет именно это, т.е. inlinehint ставится тогда и только тогда, когда есть спецификатор inline.

То есть получается вот что: inline int random() { return 4; } будет И inlinehint, И linkonce.

А вот методы, которые по Стандарту являются implicit inline functions, например:
(*) инстанциации шаблонов
(*) default и deleted члены классов, и их неявные методы
(*) методы, чей definition находится внутри definition класса
(*) constexpr- и consteval-функции (на самом деле только constexpr, т.к. consteval "испаряется" и в LLVM IR его код тупо не попадает)

... они только linkonce. Надо все равно писать ключевое слово inline, чтобы было linkonce+inlinehint.

Если бы я мог редактировать стандарт, я бы переименовал inline functions в linkonce functions, потому что текущее описание в Стандарте сильно запутывает...

Интересные вопросы:
(1) Так ли сильно влияет наличие атрибута inlinehint на компиляцию? Я слышал, что компиляторы уже давно не обращают внимание на подобные подсказки...
Влияет практически незаметно. Порог для инлайнинга у обычного метода 225 попугаев, для inlinehint-метода 325 попугаев (ссылка на код), а для реальной разницы нужно ~1000 попугаев.

То есть в 99% кейсов inline constexpr void foo() и constexpr void foo() будут вести себя одинаково, однако в clang-tidy не принимают патч на удаление redundant inline, потому что остается какой-то непонятный 1% кейсов.

(2) Почему один атрибут вытекает из другого, если они ортогональны?
Чтобы компилятор мог в translation unit заинлайнить (inlinehint) функцию, TU нужно "видеть" исходник этой функции, то есть её тело. В общем случае это невозможно обеспечить, потому что если у нас N штук TU, то будет N определений одной и той же функции и линкер сломается. Поэтому эта функция должна являться linkonce, чтобы не нарушился ODR.

BY C++95


Warning: Undefined variable $i in /var/www/group-telegram/post.php on line 260

Share with your friend now:
group-telegram.com/cxx95/37

View MORE
Open in Telegram


Telegram | DID YOU KNOW?

Date: |

Overall, extreme levels of fear in the market seems to have morphed into something more resembling concern. For example, the Cboe Volatility Index fell from its 2022 peak of 36, which it hit Monday, to around 30 on Friday, a sign of easing tensions. Meanwhile, while the price of WTI crude oil slipped from Sunday’s multiyear high $130 of barrel to $109 a pop. Markets have been expecting heavy restrictions on Russian oil, some of which the U.S. has already imposed, and that would reduce the global supply and bring about even more burdensome inflation. Elsewhere, version 8.6 of Telegram integrates the in-app camera option into the gallery, while a new navigation bar gives quick access to photos, files, location sharing, and more. 'Wild West' Such instructions could actually endanger people — citizens receive air strike warnings via smartphone alerts. Continuing its crackdown against entities allegedly involved in a front-running scam using messaging app Telegram, Sebi on Thursday carried out search and seizure operations at the premises of eight entities in multiple locations across the country.
from us


Telegram C++95
FROM American