cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

Принять в стандарт С++ расширения gcc C и gcc C++ #396

Open apolukhin opened 3 years ago

apolukhin commented 3 years ago

Перенос предложения: голоса +11, -3 Автор идеи: NeoProgramming

В компиляторе gcc реализовано множество полезных расширений. В отличие от множества новых проектируемых возможностей языка, нередко весьма сложных даже для понимания, данные расширения простые, они проверены и работают. Их давно следует стандартизировать.

Расширения Си: https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html

Расширения С++: https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Extensions.html

Не знаю, нужно ли их здесь все перечислять. Некоторые расширения Си уже реализованы в новейших версиях Си и С++. Но в целом там очень много полезного.

Моя статья на Хабре https://habr.com/post/315676/ , там достаточно подробно все расписано. Впрочем, если модераторы посчитают нужным, можно просто вставить текст оттуда.

apolukhin commented 3 years ago

yndx-antoshkka, 26 декабря 2018, 12:38 Давайте по каждой конкрентой фиче проходиться отдельно. Всё сразу не примут, часть расширений - опасные и от них отказываются, часть уже принята в C++20/C++17.

Давайте начнём с ТОП-5 вещей, которые вы бы хотели видеть в C++. Что по вашему мнению самое полезное из этих расширений https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Extensions.html ?

Antervis, 27 декабря 2018, 11:33 yndx-antoshkka, target - автодиспатч по архитектурам. Очень приятная штука

yndx-antoshkka, 27 декабря 2018, 11:41 Antervis, учтите, что придётся стандартизировать имена популярных архитектур. Вы готовы взяться за черновик?

Antervis, 27 декабря 2018, 12:57 yndx-antoshkka, а имена архитектур точно необходимо стандартизировать? Дело даже не в том, что их много, а в том, что target также поддерживает dispatch по наборам инструкций. Во-первых, стандартизация всяких AVX512VPOPCNTDQ будет попросту отставать по времени от потребности, а во-вторых, архитектуры как правило являются суперсетами других архитектур. Разве нельзя обойтись правилами компиляции и выбора перегрузок? Навскидку, можно сформулировать как-то так: Функция компилируется в соответствии со всеми переданными target'ами. Если компилятор не знает указанную архитектуру (в конкретном режиме) - пропустить компиляцию функции, выдать диагностическое сообщение. Во время выполнения выбирается наиболее подходящая перегрузка по архитектуре, по принципу наиболее полного набора target'ов и его сабсетов.

yndx-antoshkka, 28 декабря 2018, 11:29 Antervis, тогда полтеряется смысл в этой штуке - производители будут лепить свои имена таргетов, не совместимые с именами других компиляторов. Если в зависимости от компилятора придётся через макросы выбирать таргет - то получается стрёмно и непереносимо.

Antervis, 28 декабря 2018, 11:50 yndx-antoshkka, а к стандарту вообще есть приложения с более коротким циклом обновления?

yndx-antoshkka, 28 декабря 2018, 14:31 Antervis, можно начать с таргетов не привязанных к конкретным платформам. Например native (текущая платформа), basic (текущие настройки компилятора), all (нагенерить для всех возможных платформ)

Antervis, 28 декабря 2018, 18:24 yndx-antoshkka, вряд ли платформонезависимые варианты all/basic/default/native помогут для значимого процента юзкейсов. А можно сослаться на какой-то другой документ с перечислением существующих платформ/архитектур, их иерархий и наименований?

yndx-antoshkka, 10 января 2019, 12:17 Antervis, да, можно сослаться. Главное чтобы такой документ нашёлся.

iksk810, 26 декабря 2018, 13:14 Элвис-оператор было бы неплохо принять. Мелочь, а приятно. )

Игорь Шаповал, 26 декабря 2018, 13:48 Хотелось бы чтобы приняли switch c диапазоном значений

switch (number) {
case 1 ... 5:
    // code
    break;
default:
    // code
} 

Игорь Шаповал, 28 декабря 2018, 14:09 А что поповоду switch c диапазоном значений? Мне кажется недолжно быть проблем чтобы добавить в стандарт.

yndx-antoshkka, 10 января 2019, 12:19 Игорь Шаповал, что-то подобное обсуждается вот тут http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1308r0.html . Я сильно против этого предложения - выглядит по уродски, читать не удобно.

yndx-antoshkka, 3 октября 2019, 11:52 Тут в видео озвучиваются популярные расширения C++, которые есть почти что во всех компиляторах: https://youtu.be/IAdLwUXRUvg

Можно начать с их стандартизации. Есть желающие нписать proposal?

Andrey, 10 октября 2019, 14:19 yndx-antoshkka, я бы очень хотел, чтобы такой код (де факто повсеместно использующийся)

template<typename Scalar>
struct vec3 {
  union {
     struct {
       Scalar x, y, z;
     };
     struct {
       Scalar r, g, b;
     };
     Scalar v[3];
  };
};

стал де юре компилирующимся и не содержащим UB C++.

Задача разбивается на 2 (вполне независимых) proposals:

  1. Anonymous structs, по аналогии c anonymous union. Не вижу тут вообще никаких препятствий -- ни технических (одна страница стандарта, по аналогии с http://eel.is/c++draft/class.union.anon#:restriction,anonymous_union), ни идеологических (очевидно полезная вещь), ни оппозиции со стороны разработчиков компиляторов -- у них это уже реализовано.

  2. Сделать T[N] и struct { T v_1, Т v_2, ..., T v_N } layout-compatible в случае когда T -- standard layout type, сразу исправив существующие UB (https://code.woboq.org/qt5/qtbase/src/gui/painting/qcolor.h.html#QColor::CT). Кажется логичным, но я не уверен на 100%, что это ничему не противоречит.

К сожалению, я не могу заняться этим до новогодних каникул. Если, кто-то возьмется писать до этого времени, буду рад :), если нет -- готов попробовать.

Игорь Гусаров, 24 января 2020, 19:49 Andrey, обеими руками голосую за то, чтобы вывести подобные конструкции из тени!

Хочу обратить внимание, что у этой задачи есть ещё и третья часть: полностью перетрясти концепцию юнионов (или ввести в язык некую новую сущность вместо union). Ведь union-типы задумывались как средство, позволяющее в каждый момент времени работать только с одним полем, а Вы, насколько я догадываюсь, предлагаете разрешить читать и модифицировать любые поля вразнобой.

Уточните, пожалуйста, желаемые сценарии использования, так как UB скорее всего кроется именно в них.

Andrey, 24 января 2020, 20:46 Игорь Гусаров, это не потребуется, все нужные механизмы для обхода UB уже есть (или на подходе). Структуры из моего примера layout-compatbile поэтому обращаться к ним вразнобой можно (http://eel.is/c++draft/class.union#2.note-1). Осталось гарантировать, чтобы они были layout-compatible c массивом, это решается proposal-ом P1912.

Игорь Гусаров, 24 января 2020, 23:06 Andrey, как Вы понимаете формулировку "it is permitted to inspect" из упомянутого пункта 11.5.2.note-1?

Мне кажется, что эта формулировка разрешает только доступ на чтение. А доступ на запись (точнее, присваивание нового значения) сразу "включает" пункт 6 того же раздела, в особенности замечание http://eel.is/c++draft/class.union#6.note-1

vec3<int>   v;

// Start the lifetime of {x,y,z} union member.
v.x = 1;
v.y = 2;

// Start the lifetime of {r,g,b} union member.
// End the lifetime of {x,y,z} union member.
v.r = 3;

// At this point:
// the lifetime of v.y object has ended
// and v.g object hasn't been initialized yet.

std::cout << v.g;  // Question: what is the value of v.g?

Andrey, 25 января 2020, 1:26 Игорь Гусаров, я на всякий случай уточнил у экспертов в slack-е (https://cpplang.slack.com/archives/C21PKDHSL/p1579903527448100), уверяют что все в порядке, и что в случае common initial sequence о прекращении времени жизни объекта {x, y, z} можно не беспокоиться (https://cpplang.slack.com/archives/C21PKDHSL/p1579904079460500). То есть мое интуитивное понимание такое, что в случае layout-compatible типов не происходит никакого переключения между активными членами union-а, они как будто одновременно живы и просто доступны под разными именами. Еще раз подчеркну, что это только в случае layout-compatible типов.

Игорь Гусаров, 27 января 2020, 19:35 Andrey, участника, который высказал такое мнение, уже поправили: https://cpplang.slack.com/archives/C21PKDHSL/p1579905163488900?thread_ts=1579903743.451200&cid=C21PKDHSL.

Andrey, 27 января 2020, 20:05 Игорь Гусаров, окей, я запутался. Мне кажется, что этот пример должен быть без UB, но похоже, что согласно текущему wording-у это не так. По-моему, это проблема wording-а, т.к. TBAA валидность этого код мешать не должна. Надо задать соответствующий вопрос либо в std-discussion mailing list-е или в том же slack-е в канале #standardese или писать в закрытый mailing list "core", где сидят настоящие wording джедаи.

Игорь Гусаров, 27 января 2020, 20:52 Andrey, ну да, о том и речь! Чтобы легализовать доступ на чтение-запись к общей начальной части понадобятся новые явные формулировки в [class.union], а возможно и в [basic.lifetime] и [intro.object]. Это тоже работа.

Про aliasing тоже согласен - данным сценариям он не мешает.

Может быть, можно начать с поисков ответа на вопрос: "Почему для общей начальной части исключение сделано только для доступа на чтения? Какие соображения помешали сразу разрешить чтение и модификацию?"