cpp-ru / ideas

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

Relax field designators order #493

Open sergii-rybin-tfs opened 2 years ago

sergii-rybin-tfs commented 2 years ago

В C++20 добавили field designators https://en.cppreference.com/w/cpp/language/aggregate_initialization.

Это замечательный функционал который может значительно расширить декларативные возможности C++, и позволит использовать язык в тех контекстах, подобных use-кейсам yml\json\css.

Но есть одна печальная оговорка, которая сводит на нет полезность этой фичи. Инициализаторы должны быть в порядке обьявления. Это приводит к тому, что автор класса диктует дизайн для инициализации, объявление становится "замороженным" после публикации интерфейса, и любой рефакторинг связанный с порядком и количеством членов класса становится дорогим и нежелательным.

Судя по компилятору Clang - https://godbolt.org/z/c9dWTrnKx , то нет проблемы компилировать код с любым порядком инициализаторов ( он это умеет делать в любой версии, но в последней с ворнингом ). Компиляторы gcc msvc - отказываются.

struct point 
{
    int x; // << хочу рефакторить порядок объявления членов класса, без изменения клиентского кода
    int y;
};

int main() {
    point a = { 
        .y=2, // << Хочу дизайнить инициализацию в любом порядке, для выражения смысла локального контекста
        .x=4,
        };

    cout << a.x << " " << a.y << endl;  
}
xaizek commented 2 years ago

Помню на подкасте Гор Нишанов прямо гордился тем, что в отличии от C они запретили инициализировать поля в неправильном порядке или не в полном объёме. Но он не объяснял, что в этом хорошего. Возможно то, что это позволяет после проверки на фронте просто выкинуть .name = и компилировать код как до C++20 (если нет никаких изменений с порядком инициализации).

sergii-rybin-tfs commented 2 years ago

По стандарту можно опускать инициализацию промежуточных элементов. Поэтому просто отбросить на фронте- не выйдет, потому что будет неопределенность. С другой стороны, всё идёт к тому, что фронт у майкрософта будет только на клэнге и всё равно сможет переварить нестандартный синтаксис.

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

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

oficsu commented 2 years ago

Интересно послушать аргументацию почему Гор считает что как в С - плохо

Думаю, по той же причине, по которой существуют -Wreorder

sergii-rybin-tfs commented 2 years ago

Думаю, по той же причине, по которой существуют -Wreorder

для филдов такой же баг как со списком инициализации в конструкторе не проходит, они by design не видят друг друга.

oficsu commented 2 years ago

О каком именно баге речь?

sergii-rybin-tfs commented 2 years ago

Распространенная проблема связана с тем, что при инициализации одного поля (в списке инициализации конструктора), берется ссылка на другое, которое еще не инициализировано.

AndreyG commented 2 years ago

для филдов такой же баг как со списком инициализации в конструкторе не проходит, они by design не видят друг друга.

Вообще-то могут видеть.

struct Point {
    int x, y;
} p {
    .y = 1,
    .x = p.y
};

И это в сочетании с переупорядочиванием инициализаторов может приводить к весьма интересным результатам.