Для инициализации структуры Point код <code>Point p = { .x = 5; }</code> из первого примера генерирует дополнительные строки кода, в то время как код из второго примера <code>Point p; p.x = 5;</code> подразумевает прямое присваивание значения переменной. Почему используют первый вариант инициализации, если он менее эффективен по времени выполнения, чем второй вариант? Гипотеза состоит в том, что первый вариант может быть более удобен при инициализации глобальных структурных переменных.
GCC генерирует дополнительные строки кода при инициализации структуры с использованием инициализаторов, таких как <code>{ .x = 5 }</code>, потому что компилятор должен быть уверен, что все члены структуры инициализированы правильно. Это обеспечивает безопасность и предотвращает ошибки в программе. Использование первого варианта инициализации может быть предпочтительным в случае глобальных структурных переменных, потому что позволяет явно указать, какой член структуры инициализируется, что упрощает читаемость кода. Кроме того, это может быть удобно, если структура имеет много членов, и инициализация их всех одновременно может быть сложной задачей. Тем не менее, в случае локальных переменных использование прямого присваивания, как во втором варианте инициализации, может быть более эффективным и простым способом инициализации переменной, особенно если инициализируется только один член структуры. Таким образом, выбор между двумя вариантами инициализации зависит от конкретной ситуации и предпочтений программиста.
Зависит от окружения/флагов/версии
Но я здесь вижу:
1. Именованная константа со своим адресом (PIC)
2. Простое число
В первом случае необходимо использовать регистр (временное хранилище), т.к. нельзя копировать из памяти в память - надо оперировать регистрами
Что у вас за опции сборки (Это же с++, не смотря на теги же?) Оптимизация-то включена? GCC 14 даже без оптимизаций выдает именно второй код в обоих случаях.
Похоже, это недочет в компиляторе. Понятно, что тут можно использовать второй вариант без проблем. Но компилятор не смог до этого догадаться по каким-то причинам. Ясно, что для списка инициализации и просто присвоения используются разные куски компилятора. И вот в ветке для списка инициализации эту оптимизацию не прикрутили по каким-то причинам.
Если вы вставите более полный пример кода на godbolt.org, воспроизведете проблему, и поделитесь ссылкой, то, возможно, я смогу вам более детально ответить.
Edit:
Разобрались, что это clang c. Такой код он выдает с -O0. Если же оптимизации включены, то он его оптимизирует. Это не недочет или ошибка. Просто, вот такой у него стандартный код. Он вправе засовывать константы в секцию данных, а не вставлять прям в ассемблерный код.
Семантически у вас в двух вариантах написаны совершенно разные вещи.
В первом случае в секции данных создаётся безымянная структура, ссылка на которую присваивается переменной p, а во втором случае записывается число в поле структуры p, автоматически размещаемой, т.е. для типичных архитектур находящейся на стеке.
На высоких уровнях оптимизации, конечно, компилятор догадается, что результат этих действий один и тот же, но формально это разные программы. По той же самой причине, по которой элементарные и агрегатные типы в языке Си различаются между собой по способу присваивания.