Почему С++ 20 не поддерживает назначенный не по порядку инициализатор?

Пока я читал справочник по C++, у меня возник вопрос по этому абзацу:

Примечание: назначенная инициализация не по порядку, вложенная назначенная инициализация, смешивание назначенных инициализаторов и обычных инициализаторов, а также назначенная инициализация массивов поддерживаются в языке программирования C, но не разрешены в C++.

Есть ли какая-либо техническая причина, которая не позволяет С++ поддерживать инициализацию не по порядку?


person Sadeq    schedule 11.11.2018    source источник
comment
Вероятно, потому, что упомянутые вещи всегда были чем-то вроде угрозы безопасности в C.   -  person Lundin    schedule 11.11.2018


Ответы (2)


Да, обоснование описано в Приложении C (информативном) Совместимость, в частности [diff.dcl]p10 (выделено мной):

Затронутый подпункт: [dcl.init.aggr] Изменение: В C++ поддержка назначенной инициализации ограничена по сравнению с соответствующей функциональностью в C. В C++ указатели для нестатических элементов данных должны указываться в порядке объявления, указатели для элементов массива и вложенные указатели не поддерживаются, и назначенные и не назначенные инициализаторы не могут быть смешаны в одном и том же списке инициализаторов. Пример:

struct A { int x, y; };
struct B { struct A a; };
struct A a = {.y = 1, .x = 2};  // valid C, invalid C++
int arr[3] = {[1] = 5};         // valid C, invalid C++
struct B b = {.a.x = 0};        // valid C, invalid C++
struct A c = {.x = 1, 2};       // valid C, invalid C++

Обоснование: В C++ члены уничтожаются в обратном порядке построения, а элементы списка инициализаторов оцениваются в лексическом порядке, поэтому инициализаторы полей должны указываться по порядку. Обозначения массивов конфликтуют с синтаксисом лямбда-выражения. Вложенные указатели используются редко.

первая редакция предложения также обсуждает эту тему:

Чтобы оправдать эти ожидания гарантированного удаления копии, мы требуем, чтобы указатели отображались как подпоследовательность последовательности объявления элементов данных, чтобы порядок оценки соответствовал порядку объявления, а также текстуально слева направо в назначенной инициализации.

Вы можете получить последнюю версию здесь.

person Shafik Yaghmour    schedule 11.11.2018
comment
Недавно я провел по этому поводу опрос в Твиттере. - person Shafik Yaghmour; 11.11.2018
comment
Я не вижу проблемы, если бы это было указано как: порядок инициализации будет таким же, как порядок членов. Это случилось со списком инициализации уже раньше. Есть ли негативные последствия, если это допустить? - person Germán Diago; 30.01.2019
comment
@GermánDiago, я думаю, они считают это (разрешение произвольного порядка в списке инициализации членов) плохим дизайнерским решением и не хотят распространять его дальше: в конце концов, надеюсь, что большинство программистов все равно никогда не нарушат этот порядок, благодаря -Wall. - person GreenScape; 10.09.2019

Наличие только небольшой части назначенных опций инициализации из C болезненно. Возможно, в будущем это будет исправлено. На данный момент некоторые компиляторы немного менее строги, чем стандарт C++20. Этот фрагмент:

struct A {int x, y;};
A a = {.y=2, .x=4};

компилируется с предупреждением и нормально работает с clang-10.0.0 и новее (см. https://godbolt.org/z/Ybnzz5chx).

person Paul Jurczak    schedule 16.04.2021