Making all instances of tag types inline

Anton Bikineev
Anton Bikineev

Расммотрим 3.2.6.2 [basic.def.odr]:

in each definition of D, corresponding names, looked up accordingly to 3.4, shall refer to an entity defined within the definition of D, or shall refer  to the same entity, after overload resolution and after matching of partial template specialization, except that a name can refer to

- a non-volatile const object with internal or no linkage if the object

  - has the same literal type in all definitions of D,

  - is initialized with a constant expression,

  - is not odr-used, and

  - has the same value in all definitions of D.

Теперь рассмотрим, к примеру, пример определения экзекьюшн-политики и параллельного алгоритма в стандартной библиотеке:

constexpr sequential_execution_policy seq{};

template<class ExecutionPolicy, class InputIterator>
typename std::iterator_traits<InputIt>::value_type reduce(
    ExecutionPolicy&& policy, InputIt first, InputIt last);

Видно, что передача параметра по ссылке делает переменную odr-used. Следовательно, любой вызов алгоритма в инлайновой функции или шаблонной функции, определенной в различных единицах трансляции, приводит к odr-нарушению.

Выдвигается идея сделать следующие объекты из стандартной библиотеки инлайновыми:

  • std::placeholders::_1, ...
  • piecewise_construct
  • allocator_arg
  • nullopt
  • ignore
  • defer_lock
  • try_to_lock
  • adopt_lock
  • seq
  • par
  • par_unseq

Данная проблема также рассмотрена в National Body комментах (GB28, FI9).

 

 

5
рейтинг
5 комментариев
Михаил Мальцев
С placeholder-ами таких проблем быть не должно, т.к. они "extern const", а не "constexpr":
github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/src/c%2B%2B11/placeholders.cc
Михаил Мальцев
Anton Bikineev
Михаил Мальцев,
Миша, это только в libstdc++ имплементации. Стандарт же говорит [20.14.10.4.2]:
Placeholders should be defined as:
constexpr unspecified _1{};
If they are not, they shall be declared as:
extern unspecified _1;
Anton Bikineev
yndx-antoshkka
Проверил логи заседания. GB28 было отправлено в LEWG для того, чтобы определить каким именно методом решать эту проблему: просто добавить недостающие inline, либо сделать чтобы constexpr для переменных автоматически добавлял Inline (как он сейчас делает для функций). В LEWG возникли вопросы по поводу ABI и решение было отложено на след заседание.

Если есть желание помочь с этой проблемой, стоит написать proposal, в котором исследовать влияние добавления inline на ABI для clang и gcc. В нём же, стоит попробовать сформулировать "патч" к стандарту, который говорит что constexpr автоматически добавляет inline и для переменных тоже. Готов всячески помогать при написании proposal (но сделать всё самостоятельно к концу января не смогу).
yndx-antoshkka
Anatoly Scheglov
Уже предлагали всякие Inline Variables open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4424.pdf
Anatoly Scheglov
yndx-antoshkka
Исправили в C++17. Пометили теги и все шаблонные переменные как inline в p0607r0.

Меня немного волнует, что эти переменные получили таким образом external linkage вместо internal linkage. Но волнует не настолько сильно, чтобы думать о том как это исправить.
yndx-antoshkka
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).