- 1
while(new char != NULL) {}
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
−17
while(new char != NULL) {}
CTEPTOP 23.02.2017 00:36 # 0
CTEPTOP 23.02.2017 11:50 # −1
Bobik 23.02.2017 12:04 # 0
Bobik 23.02.2017 12:05 # 0
CTEPTOP 23.02.2017 13:10 # +1
В Делфи большинство объектов имеют фабрику (конструкторы там всякие, деструкторы), а здесь объект инициализируется именно вызовом new.
Вот, что штампуют в википездии:
new — оператор языка программирования C++, обеспечивающий выделение динамической памяти в куче. За исключением формы, называемой «размещающей формой new», new пытается выделить достаточно памяти в куче для размещения новых данных и, в случае успеха, возвращает адрес выделенного участка памяти. Однако, если new не может выделить память в куче, то он передаст (throw) исключение типа std::bad_alloc. Это устраняет необходимость явной проверки результата выделения. После встречи компилятором ключевого слова new им генерируется вызов конструктора класса[1].
Bobik 23.02.2017 13:22 # +1
inkanus-gray 23.02.2017 14:36 # +1
> Однако, если new не может выделить память в куче, то он передаст (throw) исключение типа std::bad_alloc.
А вот это уже ценное замечание. Если в случае неудачи аллокатор бросает исключение и никогда не возвращает NULL, то данный код компилятор может оптимизировать до такого:
Всё равно выход из цикла только по исключению.
Тем не менее, «неоптимизированная» форма ошибкой не является. Ошибкой является то, что мы никуда не сохраняем полученный указатель.
guest 23.02.2017 23:40 # 0
inkanus-gray 24.02.2017 00:12 # +1
guest 24.02.2017 00:41 # +2
Bobik 24.02.2017 02:14 # +2
guest 24.02.2017 02:43 # 0
Bobik 24.02.2017 09:37 # 0
new может быть определён пользователем и следует другому контракту: либо кидает исключение, либо выдаёт новый кусочек памяти. Оптимизации всё равно должны учитывать оба варианта этого поведения.
guest 24.02.2017 12:26 # −1
Bobik 24.02.2017 12:37 # 0
guest 24.02.2017 02:53 # 0
http://stackoverflow.com/questions/31873616/is-the-compiler-allowed-to-optimize-out-heap-memory-allocations
> This is allowed by N3664. This proposal is part of the C++14 standard, so in C++14 the compiler is allowed to optimize out a new expression (even if it might throw).
Bobik 24.02.2017 09:30 # 0
An implementation is allowed to omit a call to a replaceable global allocation function (18.6.1.1, 18.6.1.2). When it does so, the storage is instead provided by the implementation or provided by extending the allocation of another new-expression. The implementation may extend the allocation of a new-expression e1 to provide storage for a new-expression e2 if the lifetime of the object allocated by e1 strictly contains the lifetime of the object allocated by e2, e1 and e2 would invoke the same replaceable global allocation function, and, for a throwing allocation function, exceptions in e1 and e2 would be first caught in the same handler.
Выкинутый new обязательно должен быть склеен с другим new (то есть хотя бы один new должен остаться), либо результат должен быть "provided by the implementation", а никакая реализация не сможет бесконечно выделять новую память, и в конце концов кинет исключение.
bormand 24.02.2017 10:23 # 0
Т.е. в общем-то и на стеке может запилить, если увидит пару из new и delete, а указатель наружу не утекает.
guest 24.02.2017 12:28 # 0
guest 24.02.2017 12:33 # 0
Вот шланг выпиливает new из кода выше https://godbolt.org/g/QrWwRk
Bobik 24.02.2017 12:38 # 0
guest 24.02.2017 12:55 # 0
Bobik 24.02.2017 13:46 # 0
https://godbolt.org/g/FveCUw
Видимо, тут он пользуется какими-то своими знаниями о дефолтном операторе new, а не о конструкции выделения памяти.
Antervis 24.02.2017 13:39 # +1
Bobik 24.02.2017 13:45 # +1
bormand 24.02.2017 13:59 # 0
Antervis 24.02.2017 16:11 # 0
Psionic 24.02.2017 02:56 # 0
inkanus-gray 24.02.2017 09:20 # 0
guest 03.03.2017 18:37 # 0
inho 23.02.2017 00:42 # +1
1024-- 23.02.2017 11:42 # +5