Локальные переменные
От: LaptevVV Россия  
Дата: 17.08.25 07:30
Оценка: :))
Вопрос: в с++20 локальные переменные стали зануляться по стандарту ?
Помнится вроде в clang они давно занулялись.
Сейчас стали обнуляться и в gcc.
В n4868 в 9.4 написано только
To zero-initialize an object or reference of type T means:
(6.1) — if T is a scalar type (6.8), the object is initialized to the value obtained by converting the integer literal 0 (zero) to T;
Относится ли это к локальным переменным — непонятно.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: Локальные переменные
От: rg45 СССР  
Дата: 17.08.25 08:58
Оценка: +3
Здравствуйте, LaptevVV, Вы писали:

LVV>Вопрос: в с++20 локальные переменные стали зануляться по стандарту ?

LVV>Помнится вроде в clang они давно занулялись.
LVV>Сейчас стали обнуляться и в gcc.
LVV>В n4868 в 9.4 написано только
LVV>To zero-initialize an object or reference of type T means:
LVV>(6.1) — if T is a scalar type (6.8), the object is initialized to the value obtained by converting the integer literal 0 (zero) to T;
LVV>Относится ли это к локальным переменным — непонятно.

В этом пункте расписано, что из себя представляет zero-initialization, а не когда она применяется. А чтоб понять применение, там нужно отслеживать целую цепочку пунктов, включая пункты из других разделов. И заканчивается эта цепочка вот здесь: https://timsong-cpp.github.io/cppwp/dcl.init.general#7.4

(7.3) — Otherwise, no initialization is performed.


Наиболее интересным в данном контексте является, пожалуй, вот этот пункт (С++20):

https://timsong-cpp.github.io/cppwp/n4861/basic.indet#1

6.7.4 Indeterminate values
1 When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced ([expr.ass]). [ Note: Objects with static or thread storage duration are zero-initialized, see [basic.start.static]. — end note]


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

Как подкрепление сказанному, практический пример (С++26):

http://coliru.stacked-crooked.com/a/2b259fe0bb7256ac

#include <iostream>

int x;

int main() {
    int y;
    std::cout << x << std::endl;    // OK
    std::cout << y << std::endl;    // warning: 'y' is used uninitialized [-Wuninitialized]
}
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 17.08.2025 9:46 rg45 . Предыдущая версия . Еще …
Отредактировано 17.08.2025 9:45 rg45 . Предыдущая версия .
Отредактировано 17.08.2025 9:43 rg45 . Предыдущая версия .
Отредактировано 17.08.2025 9:43 rg45 . Предыдущая версия .
Отредактировано 17.08.2025 9:07 rg45 . Предыдущая версия .
Отредактировано 17.08.2025 9:04 rg45 . Предыдущая версия .
Отредактировано 17.08.2025 9:03 rg45 . Предыдущая версия .
Отредактировано 17.08.2025 9:02 rg45 . Предыдущая версия .
Re[2]: Локальные переменные
От: kov_serg Россия  
Дата: 17.08.25 11:05
Оценка:
Здравствуйте, rg45, Вы писали:

R>
R>#include <iostream>

R>int x;

R>int main() {
R>    int y;
R>    std::cout << x << std::endl;    // OK
R>    std::cout << y << std::endl;    // warning: 'y' is used uninitialized [-Wuninitialized]
R>} // а где warning no return value ?
R>
Re[3]: Локальные переменные
От: rg45 СССР  
Дата: 17.08.25 11:16
Оценка: +1
Здравствуйте, kov_serg, Вы писали:

R>>
R>>#include <iostream>

R>>int x;

R>>int main() {
R>>    int y;
R>>    std::cout << x << std::endl;    // OK
R>>    std::cout << y << std::endl;    // warning: 'y' is used uninitialized [-Wuninitialized]
R>>} // а где warning no return value ?
R>>


Ну хорош уже душнить. Отсустствие return в main трактуется как return 0;

https://timsong-cpp.github.io/cppwp/n4861/basic.start.main#5

6.9.3.1 main function
5 A return statement ([stmt.return]) in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std​::​exit with the return value as the argument. If control flows off the end of the compound-statement of main, the effect is equivalent to a return with operand 0 (see also [except.handle]).


А также:

https://timsong-cpp.github.io/cppwp/n4861/stmt.return#2

8.7.3 The return statement
2 . . . Otherwise, flowing off the end of a function other than main or a coroutine ([dcl.fct.def.coroutine]) results in undefined behavior.

--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 17.08.2025 11:40 rg45 . Предыдущая версия . Еще …
Отредактировано 17.08.2025 11:22 rg45 . Предыдущая версия .
Отредактировано 17.08.2025 11:21 rg45 . Предыдущая версия .
Отредактировано 17.08.2025 11:18 rg45 . Предыдущая версия .
Re: Локальные переменные
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 17.08.25 11:48
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Помнится вроде в clang они давно занулялись.

LVV>Сейчас стали обнуляться и в gcc.

Куда правильнее было бы по дефолту заносить либо предопределенные, либо случайные значения, а нулями инициализировать только при явном запросе (ключ компилятора, прагма, атрибут и т.п.).
Re[2]: Локальные переменные
От: rg45 СССР  
Дата: 17.08.25 11:53
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Куда правильнее было бы по дефолту заносить либо предопределенные, либо случайные значения, а нулями инициализировать только при явном запросе (ключ компилятора, прагма, атрибут и т.п.).


Это приемлемо как отладочная мера (которая и так используется). А в релизной конфигурации это может оказаться лишней работой, которая чувствительно влияет на производительность. Ведь стандарт разрешает неинициализированную переменную инициализировать позже (например, через присваивание). Ведь не просто так в стандартную библиотеку вводится куча "uninitialized_..." алгоритмов, позволяющих избежать ненужной промежуточной инициализации.
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 17.08.2025 11:58 rg45 . Предыдущая версия .
Re[2]: Локальные переменные
От: LaptevVV Россия  
Дата: 17.08.25 12:18
Оценка:
Спасибо.
R>В этом пункте расписано, что из себя представляет zero-initialization, а не когда она применяется. А чтоб понять применение, там нужно отслеживать целую цепочку пунктов, включая пункты из других разделов. И заканчивается эта цепочка вот здесь: https://timsong-cpp.github.io/cppwp/dcl.init.general#7.4
R>

R>(7.3) — Otherwise, no initialization is performed.

Да, это я тоже читал.
R>Наиболее интересным в данном контексте является, пожалуй, вот этот пункт (С++20):
R>https://timsong-cpp.github.io/cppwp/n4861/basic.indet#1
R>

R>6.7.4 Indeterminate values
R>1 When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced ([expr.ass]). [ Note: Objects with static or thread storage duration are zero-initialized, see [basic.start.static]. — end note]

R>В общем, принципиальных изменений не наблюдается. А то, что в каких-то отдельных случаях неинициализированные переменные содержат нули, следует трактовать просто как стечение обстоятельств, я думаю.
Просто в мингв 12.2 локальные переменные точно не обнулялись.
А сейчас в мингв 14.2 что-то непонятно.

R>Как подкрепление сказанному, практический пример (С++26):

Ну, до С++26 еще пилить и пилить.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[3]: Локальные переменные
От: rg45 СССР  
Дата: 17.08.25 12:28
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Просто в мингв 12.2 локальные переменные точно не обнулялись.

LVV>А сейчас в мингв 14.2 что-то непонятно.

Я думаю, все это следует трактовать как проявление UB:

https://timsong-cpp.github.io/cppwp/n4861/basic.indet#2

If an indeterminate value is produced by an evaluation, the behavior is undefined . . .


R>>Как подкрепление сказанному, практический пример (С++26):

LVV>Ну, до С++26 еще пилить и пилить.

Так если даже в C++26 ничего не поменялось со времен C++03, то во всех промежуточных версиях и подавно. Вот, то же самое и в C++20: http://coliru.stacked-crooked.com/a/5f5630021077304b, и в C++03: http://coliru.stacked-crooked.com/a/946d0caf85acc1ec
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 17.08.2025 12:44 rg45 . Предыдущая версия .
Re[3]: Локальные переменные
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 17.08.25 13:47
Оценка:
Здравствуйте, rg45, Вы писали:

R>Это приемлемо как отладочная мера (которая и так используется). А в релизной конфигурации это может оказаться лишней работой, которая чувствительно влияет на производительность.


Угу, я только про отладочную и говорил, забыл это отметить.
Re[4]: Локальные переменные
От: kov_serg Россия  
Дата: 17.08.25 15:08
Оценка: +2 :))
Здравствуйте, rg45, Вы писали:

R>https://timsong-cpp.github.io/cppwp/n4861/basic.start.main#5


R>

R>6.9.3.1 main function
R>5 A return statement ([stmt.return]) in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std​::​exit with the return value as the argument. If control flows off the end of the compound-statement of main, the effect is equivalent to a return with operand 0 (see also [except.handle]).


R>А также:


R>https://timsong-cpp.github.io/cppwp/n4861/stmt.return#2


R>

R>8.7.3 The return statement
R>2 . . . Otherwise, flowing off the end of a function other than main or a coroutine ([dcl.fct.def.coroutine]) results in undefined behavior.


Вот из-за таких костылей стандарт и разрастаеся Тут так, а тут не так. Ни единообразия и соблюдения принципов. Ужос!
Re[5]: Локальные переменные
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 17.08.25 15:20
Оценка: +1 :)
Здравствуйте, kov_serg, Вы писали:

_>Вот из-за таких костылей стандарт и разрастаеся Тут так, а тут не так. Ни единообразия и соблюдения принципов. Ужос!


Да ладно. Вспомни End с точкой, или точку с запятой после операторов, но только не перед End
Маньяк Робокряк колесит по городу
Re[5]: Локальные переменные
От: rg45 СССР  
Дата: 17.08.25 15:21
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Вот из-за таких костылей стандарт и разрастаеся


С приехалом Вас. Эти требования были уже в С++03 (не уверен на счёт С++98).
--
Справедливость выше закона. А человечность выше справедливости.
Re[6]: Локальные переменные
От: wander  
Дата: 17.08.25 20:00
Оценка: 8 (1)
Здравствуйте, rg45, Вы писали:

R>(не уверен на счёт С++98).


А там всё так же.

A return statement in main has the effect of leaving the main function (destroying any objects with auto-
matic storage duration) and calling exit with the return value as the argument. If control reaches the end
of main without encountering a return statement, the effect is that of executing
return 0;

Re[6]: Локальные переменные
От: T4r4sB Россия  
Дата: 17.08.25 20:26
Оценка:
Здравствуйте, Marty, Вы писали:

M> но только не перед End


ты хотел сказать — только не перед else?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[7]: Локальные переменные
От: kov_serg Россия  
Дата: 18.08.25 11:39
Оценка:
Здравствуйте, wander, Вы писали:

W>Здравствуйте, rg45, Вы писали:


R>>(не уверен на счёт С++98).


W>А там всё так же.

W>

W>A return statement in main has the effect of leaving the main function (destroying any objects with auto-
W>matic storage duration) and calling exit with the return value as the argument. If control reaches the end
W>of main without encountering a return statement, the effect is that of executing
W>return 0;


Так я об этои и говорю, тут так а не тут UB. Вместо единообразия прдумывают 100500 способов инициализации и затейливых реализаций UB.

ps:

Когда вы узнали что вам сын наркоман. Когда из дома стали пропадать наркотики

Отредактировано 18.08.2025 11:41 kov_serg . Предыдущая версия .
Re[8]: Локальные переменные
От: wander  
Дата: 18.08.25 17:10
Оценка: +1
Здравствуйте, kov_serg, Вы писали:

_>Так я об этои и говорю, тут так а не тут UB. Вместо единообразия прдумывают 100500 способов инициализации и затейливых реализаций UB.


Справедливости ради, функция main вообще со всех сторон особенная. Например, только её нельзя вызывать, у нее фиксированные сигнатура и имя.
Re: Локальные переменные
От: Pzz Россия https://github.com/alexpevzner
Дата: 18.08.25 17:41
Оценка: +1 -2
Здравствуйте, LaptevVV, Вы писали:

LVV>Вопрос: в с++20 локальные переменные стали зануляться по стандарту ?


В Ц вряд ли. Если так сделать, настоящие крутые Ц-программеры умрут с тоски, что ихний любимый язык сделали чуть безопаснее, да еще и за их счет, отняв немного процессорных тактов.

Хотя между нами говоря, стоило бы. Может с каким специальным ключевым словом (желательно длинным, чтобы без нужды его не писали), которое явно говорит компилятору так не делать, для особо озабоченных.

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

LVV>Относится ли это к локальным переменным — непонятно.


Я б не стал рассчитывать...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.