Здравствуйте, Pavel Chikulaev, Вы писали:
E>>При lvalue-to-rvalue conversion. PC>Что общего между пунктом 4.1, UB и этим примером?
Общего то, что после освобождения памяти все указатели, указывавшие в освобожденную область, перестают быть валидными. Использование значения такого невалидного указателя приводит к неопределенному поведению (3.7.3.2/4). А доступ к этому значению происходит как раз в результате lvalue-to-rvalue conversion (4.1/2).
Re: Чем может грозить удаление POD без вызова деструктора
Здравствуйте, srggal, Вы писали:
S>Чем может грозить такое удаление( без вызова деструктора ) POD?
Падением нравов, запутанностью кода и практикованием хаков.
Вместо указателя на operator delete, передавай функцию boost::checked_delete<Foo> — которя честно сделает delete p.
Не хочешь тащить буст или прописывать в for_each тип элементов — пиши
Здравствуйте, srggal, Вы писали:
S>Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>>Для POD не нужно вызывать деструктора, т.к. по определению POD'a у него нет деструкторов или членов (в том числе и подобъектов базового класса), имеющих деструктор.
S>ГМ, он есть у POD — автоматически сгенерированный ( и что в нем — стандарт не специфицирует ), и вопрос именно в этом, чем грозит освобождение памяти занимаемой POD без вызова автоматически сгенирированного деструктора ?
S>
Ничем. Стандарт явно об этом говорит.
A program may end the lifetime of any object by reusing the storage which the object occupies or by
explicitly calling the destructor for an object of a class type with a non-trivial destructor. For an object of a
class type with a non-trivial destructor, the program is not required to call the destructor explicitly before
the storage which the object occupies is reused or released; however, if there is no explicit call to the
destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be
implicitly called and any program that depends on the side effects produced by the destructor has undefined
behavior.
Если деструктор у класса тривиальный, его можно не вызывать, а просто освободить память. Это относится как к POD типам, так и к болеее широкому класссу типов с тривиальным деструктором.
Здравствуйте, srggal, Вы писали:
S>>>А почему undefined behavior? E>>Потому что находящиеся в стандартном контейнере объекты должны быть CopyConstructible и Assignable. А получившееся там после освобождения памяти indeterminate value перестает удовлетворять этим требованиям. S>Почему Foo* т.е. value_type для контейнера — не является CopyConstructible и Assignable ? Using deleted pointers. What is undefined?.
S>// Assignable ?
S> *lst.begin() = 0; S> assert( !*lst.begin() );
Так да, а вот так: Foo* ptr = *lst.begin() — нет (формально, я-то сам всегда работаю под IA32, там такой проблемы нет).
Re[5]: Чем может грозить удаление POD без вызова деструктора
Здравствуйте, srggal, Вы писали:
S>А почему undefined behavior?
Потому что находящиеся в стандартном контейнере объекты должны быть CopyConstructible и Assignable. А получившееся там после освобождения памяти indeterminate value перестает удовлетворять этим требованиям.
Re[7]: Чем может грозить удаление POD без вызова деструктора
Здравствуйте, srggal, Вы писали:
E>>Потому что находящиеся в стандартном контейнере объекты должны быть CopyConstructible и Assignable. А получившееся там после освобождения памяти indeterminate value перестает удовлетворять этим требованиям.
S>Почему Foo* т.е. value_type для контейнера — не является CopyConstructible и Assignable ?
Является до тех пор, пока у указателей валидные значения, а когда значения указателей перестают быть валидными, то больше не является.
Foo *t, *u;
u = new Foo();
t = u; // OKdelete u;
t = u; // Undefined behavior
Re: Чем может грозить удаление POD без вызова деструктора
Для POD не нужно вызывать деструктора, т.к. по определению POD'a у него нет деструкторов или членов (в том числе и подобъектов базового класса), имеющих деструктор.
Of course, the code must be complete enough to compile and link.
Re: Чем может грозить удаление POD без вызова деструктора
А ты посмотри на вопрос под другим углом: выделяй POD стр-ру malloc(), освобождай free(). Другими словами, для POD-типов тебе не нужен дополнительный функционал new для вызова к-тора, delete для вызова д-тора.
Нет ненужного функционала, нет вопроса.
-- Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[5]: Чем может грозить удаление POD без вызова деструктора
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>А если смотреть не на этот конкретный код, а по сути исходного вопроса, позволяет ли стандарт писать так operator delete(ptr) если где-то был ptr = new POD ?
.
S>Буду курить ссылку. Но если не сложно, ответьте в форуме — Кто-же все-таки прав ?
Никакого противоречия. Единственное, что можно сделать с инвалидным указателем — это присвоить ему валидное значение. А вот читать/копировать инвалидный указатель — это уже UB.
Re[10]: Чем может грозить удаление POD без вызова деструктор
Здравствуйте, srggal, Вы писали:
S>Здравствуйте, Pavel Chikulaev, Вы писали:
PC>>Здравствуйте, elcste, Вы писали:
E>>>Является до тех пор, пока у указателей валидные значения, а когда значения указателей перестают быть валидными, то больше не является. PC>>
E>>>
E>>> Foo *t, *u;
E>>> u = new Foo();
E>>> t = u; // OK
E>>> delete u;
E>>> t = u; // Undefined behavior
E>>>
PC>>Какой UB? v.end() абсолютно нормально, пока его разыменовали, тоже самое относиться к t и u, которые оба содержать адрес на удаленный Foo.
S>Гм. приглядитесь к треду линк на которы дал Глеб здесь
Да нету никакой ложки. Проблема копирования неинициализированных значений (кроме плавающих) надуманная.
Нет её в подавляющем большинстве современных процессоров. Что касается загрузки сегментных регистров (в защищённом режиме) -- это дорогостоящая операция, поэтому копировать значение указателя таким способом ни один вменяемый компилятор не будет. Ну, кстати, стандарт C эту ситуацию адаптировал -- там введено понятие trap representation. Соответсвенно, на платформах, где у указателя нет этого trap representaion, копировать мусор можно.
Так что стандарт С++ в этом месте просто дефективен. Борьба с призраками коммунизма.
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>Для POD не нужно вызывать деструктора, т.к. по определению POD'a у него нет деструкторов или членов (в том числе и подобъектов базового класса), имеющих деструктор.
ГМ, он есть у POD — автоматически сгенерированный ( и что в нем — стандарт не специфицирует ), и вопрос именно в этом, чем грозит освобождение памяти занимаемой POD без вызова автоматически сгенирированного деструктора ?
... << RSDN@Home 1.1.4 stable rev. 510>>
Re: Чем может грозить удаление POD без вызова деструктора
Здравствуйте, elcste, Вы писали:
E>Здравствуйте, srggal, Вы писали:
S>>Чем может грозить такое удаление( без вызова деструктора ) POD?
E>Тем, что фрагмент кода внизу ill-formed и может не скомпилироваться.
Здравствуйте, Шахтер, Вы писали:
Ш>Ничем. Стандарт явно об этом говорит.
Ш>A program may end the lifetime of any object by reusing the storage which the object occupies or by Ш>explicitly calling the destructor for an object of a class type with a non-trivial destructor. For an object of a Ш>class type with a non-trivial destructor, the program is not required to call the destructor explicitly before Ш>the storage which the object occupies is reused or released; however, if there is no explicit call to the Ш>destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be Ш>implicitly called and any program that depends on the side effects produced by the destructor has undefined Ш>behavior.
Ш>Если деструктор у класса тривиальный, его можно не вызывать, а просто освободить память. Это относится как к POD типам, так и к болеее широкому класссу типов с тривиальным деструктором.
Спасибо
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[3]: Чем может грозить удаление POD без вызова деструктора
Здравствуйте, srggal, Вы писали:
S>Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>>Для POD не нужно вызывать деструктора, т.к. по определению POD'a у него нет деструкторов или членов (в том числе и подобъектов базового класса), имеющих деструктор.
S>ГМ, он есть у POD — автоматически сгенерированный ( и что в нем — стандарт не специфицирует ), и вопрос именно в
Да, надо было сказать нет определенного пользователем деструктора. Но собственно, POD имеет и другие ограничения, так что ясно, что деструктор у него — тривиальный, который как говорит стандарт ... implicitly-declared.
Of course, the code must be complete enough to compile and link.
Re[4]: Чем может грозить удаление POD без вызова деструктора
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>Здравствуйте, srggal, Вы писали:
S>>Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>>>Для POD не нужно вызывать деструктора, т.к. по определению POD'a у него нет деструкторов или членов (в том числе и подобъектов базового класса), имеющих деструктор.
S>>ГМ, он есть у POD — автоматически сгенерированный ( и что в нем — стандарт не специфицирует ), и вопрос именно в
L_L>Да, надо было сказать нет определенного пользователем деструктора. Но собственно, POD имеет и другие ограничения, так что ясно, что деструктор у него — тривиальный, который как говорит стандарт ... implicitly-declared.
Спасибо, Шахтер уже процитировал, сам я отчего не нашел в стандарте — плохо еще ориентируюсь
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[3]: Чем может грозить удаление POD без вызова деструктора
Здравствуйте, srggal, Вы писали:
S>>>Чем может грозить такое удаление( без вызова деструктора ) POD?
E>>Тем, что фрагмент кода внизу ill-formed и может не скомпилироваться.
S>Вы имеете в виду reinterpret_cast ?
Нет, я имею в виду нигде не определенный идентификатор __cdecl. Если его попросту убрать, то код будет well-formed. Но будет иметь undefined behavior. А вот как раз использование static_cast здесь единственно возможное, если его заменить на reinterpret_cast, код опять-таки будет ill-formed.
А если смотреть не на этот конкретный код, а по сути исходного вопроса, позволяет ли стандарт писать так operator delete(ptr) если где-то был ptr = new POD ?
Of course, the code must be complete enough to compile and link.
Re[5]: Чем может грозить удаление POD без вызова деструктора
ME>А ты посмотри на вопрос под другим углом: выделяй POD стр-ру malloc(), освобождай free(). Другими словами, для POD-типов тебе не нужен дополнительный функционал new для вызова к-тора, delete для вызова д-тора.
ME>Нет ненужного функционала, нет вопроса.
Но вопрос не мой, мне коллега задал вопрос, а можно ли обойтись в приведенной мной ситуации без самописного функтора, в его коде использовался new.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[4]: Чем может грозить удаление POD без вызова деструктора
S>>Вы имеете в виду reinterpret_cast ?
E>Нет, я имею в виду нигде не определенный идентификатор __cdecl. Если его попросту убрать, то код будет well-formed. Но будет иметь undefined behavior. А вот как раз использование static_cast здесь единственно возможное, если его заменить на reinterpret_cast, код опять-таки будет ill-formed.
Спасибо, уже сообразил, просто мне __cdecl уже как родной, последнее время исключительно под виндами и MSVC.
А почему undefined behavior?
Что-то я запутался
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[4]: Чем может грозить удаление POD без вызова деструктора
Ш>Если деструктор у класса тривиальный, его можно не вызывать, а просто освободить память. Это относится как к POD типам, так и к болеее широкому класссу типов с тривиальным деструктором.
А вектор POD-ов? Вроде бы на эту тему не понятно что гарантируется.
интересен так же и другой момент, а можно ли вызывать тривиальный деструктор несколько раз?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Чем может грозить удаление POD без вызова деструктора
Sorry, увлекся тем, чтобы сделать компилируемый пример, и получилось не очень хорошо. Имелось в виду использовать какой-то альтернативный механизм распределения памяти, чтобы падал еще первый operator delete.
Ну, в общем, Вы поняли.
Re[7]: Чем может грозить удаление POD без вызова деструктора
Здравствуйте, elcste, Вы писали:
E>Здравствуйте, Lorenzo_LAMAS, Вы писали:
E>Sorry, увлекся тем, чтобы сделать компилируемый пример, и получилось не очень хорошо. Имелось в виду использовать какой-то альтернативный механизм распределения памяти, чтобы падал еще первый operator delete.
E>Ну, в общем, Вы поняли.
Не совсем но при чем тут падение
Я думал о варианте с выделением через каой-нить специфический аллокатор с последующим штатным operator delete
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[8]: Чем может грозить удаление POD без вызова деструктора
Здравствуйте, elcste, Вы писали:
E>Здравствуйте, srggal, Вы писали:
S>>А почему undefined behavior?
E>Потому что находящиеся в стандартном контейнере объекты должны быть CopyConstructible и Assignable. А получившееся там после освобождения памяти indeterminate value перестает удовлетворять этим требованиям.
Почему Foo* т.е. value_type для контейнера — не является CopyConstructible и Assignable ?
Здравствуйте, Глеб Алексеев, Вы писали:
ГА>Здравствуйте, srggal, Вы писали:
S>>>>А почему undefined behavior? E>>>Потому что находящиеся в стандартном контейнере объекты должны быть CopyConstructible и Assignable. А получившееся там после освобождения памяти indeterminate value перестает удовлетворять этим требованиям. S>>Почему Foo* т.е. value_type для контейнера — не является CopyConstructible и Assignable ? ГА>Using deleted pointers. What is undefined?.
Честно гря — не знал
Век живи — век учись.
S>>// Assignable ?
S>> *lst.begin() = 0; S>> assert( !*lst.begin() ); ГА>Так да,
Т.е. таки в первоначальном фрагменте кода — нет UB, просто есть потенциальная проблема.
И, как я понял — его нет и при последующем
lst.clear();
Т.е. и деструктор списка тоже отрабатывает нормально
ГА> а вот так: Foo* ptr = *lst.begin() — нет (формально, я-то сам всегда работаю под IA32, там такой проблемы нет).
Это — уже мне понятно, но речь-то не об этом
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[8]: Чем может грозить удаление POD без вызова деструктора
Здравствуйте, Глеб Алексеев, Вы писали:
ГА>Здравствуйте, srggal, Вы писали:
S>>>>А почему undefined behavior? E>>>Потому что находящиеся в стандартном контейнере объекты должны быть CopyConstructible и Assignable. А получившееся там после освобождения памяти indeterminate value перестает удовлетворять этим требованиям. S>>Почему Foo* т.е. value_type для контейнера — не является CopyConstructible и Assignable ? ГА>Using deleted pointers. What is undefined?.
S>>// Assignable ?
S>> *lst.begin() = 0; S>> assert( !*lst.begin() ); ГА>Так да, а вот так: Foo* ptr = *lst.begin() — нет (формально, я-то сам всегда работаю под IA32, там такой проблемы нет).
Здравствуйте, elcste, Вы писали:
E>Является до тех пор, пока у указателей валидные значения, а когда значения указателей перестают быть валидными, то больше не является.
E>
E> Foo *t, *u;
E> u = new Foo();
E> t = u; // OK
E> delete u;
E> t = u; // Undefined behavior
E>
Какой UB? v.end() абсолютно нормально, пока его разыменовали, тоже самое относиться к t и u, которые оба содержать адрес на удаленный Foo.
Re[9]: Чем может грозить удаление POD без вызова деструктора
PC>Какой UB? v.end() абсолютно нормально, пока его разыменовали, тоже самое относиться к t и u, которые оба содержать адрес на удаленный Foo.
Не одно и то же. v.end() показывает точно в конец выделенного буфера, такой указатель является валидным, но его нельзя разыменовать, а u после delete u — инвалидный указатель.
зы
Я только винду переставил, Акробат Ридер еще не установил, так что в стандарт заглянуть не могу.
Re[10]: Чем может грозить удаление POD без вызова деструктор
Здравствуйте, Глеб Алексеев, Вы писали:
ГА>Не одно и то же. v.end() показывает точно в конец выделенного буфера, такой указатель является валидным, но его нельзя разыменовать, а u после delete u — инвалидный указатель.
нет это одинаковые указатели, а вот можно ли копировать не валидный указатель, эт вопрос, пошел смотреть в стандарт...
Re[9]: Чем может грозить удаление POD без вызова деструктора
.
S>>Буду курить ссылку. Но если не сложно, ответьте в форуме — Кто-же все-таки прав ?
ГА>Никакого противоречия. Единственное, что можно сделать с инвалидным указателем — это присвоить ему валидное значение. А вот читать/копировать инвалидный указатель — это уже UB.
Блин поэтому и на brainbench у меня 4.21 получилось — невнимательный , пригляделся к примеру — да все Ок — нет противоречия.
Соответсвенно UB в коде нет
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[9]: Чем может грозить удаление POD без вызова деструктора
Здравствуйте, Pavel Chikulaev, Вы писали:
PC>Здравствуйте, elcste, Вы писали:
E>>Является до тех пор, пока у указателей валидные значения, а когда значения указателей перестают быть валидными, то больше не является. PC>
E>>
E>> Foo *t, *u;
E>> u = new Foo();
E>> t = u; // OK
E>> delete u;
E>> t = u; // Undefined behavior
E>>
PC>Какой UB? v.end() абсолютно нормально, пока его разыменовали, тоже самое относиться к t и u, которые оба содержать адрес на удаленный Foo.
Гм. приглядитесь к треду линк на которы дал Глеб здесь
Здравствуйте, elcste, Вы писали:
E>При lvalue-to-rvalue conversion.
Что общего между пунктом 4.1, UB и этим примером?
E>К сожалению, это не так. Тема избитая, так что можете поискать информацию об этом. Кажется, в этом треде уже была ссылка.
Хотел удалить сообщение, но на него уже ответили, ссылку прочитал, только хотелось бы ссылку на стандарт, в другое не верю, даже Andrew Koenigу
Re[2]: Чем может грозить удаление POD без вызова деструктора
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, srggal, Вы писали:
S>>Чем может грозить такое удаление( без вызова деструктора ) POD?
К>Падением нравов, запутанностью кода и практикованием хаков. К>Вместо указателя на operator delete, передавай функцию boost::checked_delete<Foo> — которя честно сделает delete p. К>Не хочешь тащить буст или прописывать в for_each тип элементов — пиши К>
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Шахтер, Вы писали:
Ш>>Если деструктор у класса тривиальный, его можно не вызывать, а просто освободить память. Это относится как к POD типам, так и к болеее широкому класссу типов с тривиальным деструктором.
E>А вектор POD-ов? Вроде бы на эту тему не понятно что гарантируется.
То же самое. Единственное, если ты создаёшь вектор c помощью new, то освобождать память надо с помощью delete[].
E>интересен так же и другой момент, а можно ли вызывать тривиальный деструктор несколько раз?
Это интересный вопрос. Боюсь, что стандарт не разрешает подобное (впрочем, для POD типов это может быть законным -- из-за особенностей life-time для этого класса объектов). Но с другой стороны, с практической точки зрения проблем быть не должно.
Я правда, категорически не рекомендую так делать. Причина -- сегодня у класса тривиальный деструктор, а завтра ты просто вставил поле тип string -- и всё, фейерверк.
Здравствуйте, elcste, Вы писали:
E>Здравствуйте, Pavel Chikulaev, Вы писали:
E>>>При lvalue-to-rvalue conversion. PC>>Что общего между пунктом 4.1, UB и этим примером?
E>Общего то, что после освобождения памяти все указатели, указывавшие в освобожденную область, перестают быть валидными. Использование значения такого невалидного указателя приводит к неопределенному поведению (3.7.3.2/4). А доступ к этому значению происходит как раз в результате lvalue-to-rvalue conversion (4.1/2).
Эти строки заставляют задуматься. Hack заключается в том, что верхняя строка закомментирована? Потому что проблема вызова memcpy для перекрывающихся областей надуманная. В подавляющем большинстве современных реализаций копирование области самой в себя не вызовет никаких действий. Правильно я понял ход мысли?
Re[14]: Чем может грозить удаление POD без вызова деструктор
elcste wrote:
> Эти строки заставляют задуматься. Hack заключается в том, что верхняя > строка закомментирована? Потому что проблема вызова memcpy для > перекрывающихся областей надуманная.
Очень даже не надуманая. libc и MS CRT будут неправильно работать
с перекрывающимися областями.
Для корректной работы надо использовать memmove — она с ними нормально
работает.
--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 1.9
Sapienti sat!
Re[6]: Чем может грозить удаление POD без вызова деструктора
Здравствуйте, Шахтер, Вы писали:
E>>интересен так же и другой момент, а можно ли вызывать тривиальный деструктор несколько раз? Ш>Это интересный вопрос. Боюсь, что стандарт не разрешает подобное (впрочем, для POD типов это может быть законным -- из-за особенностей life-time для этого класса объектов). Но с другой стороны, с практической точки зрения проблем быть не должно. Ш>Я правда, категорически не рекомендую так делать. Причина -- сегодня у класса тривиальный деструктор, а завтра ты просто вставил поле тип string -- и всё, фейерверк.
Ну это-то понятно
Но все такиевопросы обычно связаны с какой-то странной оптимизацией
Но в целом мне кажется, что это всё таки сугубо академический интерес
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: Чем может грозить удаление POD без вызова деструктора
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Шахтер, Вы писали:
E>>>интересен так же и другой момент, а можно ли вызывать тривиальный деструктор несколько раз? Ш>>Это интересный вопрос. Боюсь, что стандарт не разрешает подобное (впрочем, для POD типов это может быть законным -- из-за особенностей life-time для этого класса объектов). Но с другой стороны, с практической точки зрения проблем быть не должно. Ш>>Я правда, категорически не рекомендую так делать. Причина -- сегодня у класса тривиальный деструктор, а завтра ты просто вставил поле тип string -- и всё, фейерверк.
E>Ну это-то понятно E>Но все такиевопросы обычно связаны с какой-то странной оптимизацией E>Но в целом мне кажется, что это всё таки сугубо академический интерес
Здравствуйте, elcste, Вы писали:
E>Здравствуйте, Шахтер, Вы писали:
Ш>>Можно сделать вот такой враппер.
E>У оберток вокруг POD бывает множество разных достоинств, но обычно у них один общий недостаток: они перестают быть POD.
E>
E>Эти строки заставляют задуматься. Hack заключается в том, что верхняя строка закомментирована? Потому что проблема вызова memcpy для перекрывающихся областей надуманная. В подавляющем большинстве современных реализаций копирование области самой в себя не вызовет никаких действий. Правильно я понял ход мысли?
Да. На самом деле, компилятор просто развернёт это место в несколько операций обмена памяти с регистрами.
Здравствуйте, Cyberax, Вы писали:
C>elcste wrote:
>> Эти строки заставляют задуматься. Hack заключается в том, что верхняя >> строка закомментирована? Потому что проблема вызова memcpy для >> перекрывающихся областей надуманная.
C>Очень даже не надуманая. libc и MS CRT будут неправильно работать C>с перекрывающимися областями.
В данном случае речь идет не о перекрытии, а о совпадении.
C>Для корректной работы надо использовать memmove — она с ними нормально C>работает.
C>-- C>С уважением, C> Alex Besogonov (alexy@izh.com)
Здравствуйте, Шахтер, Вы писали:
Ш>Да нету никакой ложки. Проблема копирования неинициализированных значений (кроме плавающих) надуманная. Ш>Нет её в подавляющем большинстве современных процессоров. Что касается загрузки сегментных регистров (в защищённом режиме) -- это дорогостоящая операция, поэтому копировать значение указателя таким способом ни один вменяемый компилятор не будет. Ну, кстати, стандарт C эту ситуацию адаптировал -- там введено понятие trap representation. Соответсвенно, на платформах, где у указателя нет этого trap representaion, копировать мусор можно. Ш>Так что стандарт С++ в этом месте просто дефективен. Борьба с призраками коммунизма.
Поиск по сайту комитета не дал каких-либо надежд, что это исправят.
Из интересного нашел только это:
312. "use" of invalid pointer value not defined
Section: 3.7.3.2 basic.stc.dynamic.deallocation Status: open Submitter: Martin von Loewis Date: 20 Sep 2001
3.7.3.2 basic.stc.dynamic.deallocation paragraph 4 mentions that the effect of using an invalid pointer value is undefined. However, the standard never says what it means to 'use' a value.
There are a number of possible interpretations, but it appears that each of them leads to undesired conclusions:
A value is 'used' in a program if a variable holding this value appears in an expression that is evaluated. This interpretation would render the sequence
int *x = new int(0);
delete x;
x = 0;
into undefined behaviour. As this is a common idiom, this is clearly undesirable.
A value is 'used' if an expression evaluates to that value. This would render the sequence
int *x = new int(0);
delete x;
x->~int();
into undefined behaviour; according to 5.2.4 expr.pseudo, the variable x is 'evaluated' as part of evaluating the pseudo destructor call. This, in turn, would mean that all containers (23 lib.containers) of pointers show undefined behaviour, e.g. 23.2.2.3 lib.list.modifiers requires to invoke the destructor as part of the clear() method of the container.
If any other meaning was intended for 'using an expression', that meaning should be stated explicitly.
Объясните плиз в чем разница:
int * p = new int();
delete p;
p; //UB
vector<int> v;
bool found = find(v.begin(), v.end(), SomeFunctor(args)) != v.end(); //well-formed?
Там же тоже никакого объекта не находится? Но UB почему-то нет...
Или на платформах где это действительно UB, там находится еще один объект?
Re[12]: Чем может грозить удаление POD без вызова деструктор
Pavel Chikulaev wrote:
> Там же тоже никакого объекта не находится? Но UB почему-то нет... > Или на платформах где это действительно UB, там находится еще один объект?
Насколько я знаю, one-past-the-last итератор должен быть валиден для
сравнения. Ну а как он будет сделан — неважно.
--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 1.9
Sapienti sat!
Re[13]: Чем может грозить удаление POD без вызова деструктор
Здравствуйте, Cyberax, Вы писали:
C>Pavel Chikulaev wrote:
>> Там же тоже никакого объекта не находится? Но UB почему-то нет... >> Или на платформах где это действительно UB, там находится еще один объект?
C>Насколько я знаю, one-past-the-last итератор должен быть валиден для C>сравнения. Ну а как он будет сделан — неважно.
Ужас
[offtopic]
Я узнал почему я не добрал на Brainbench'е 0.12 Вопрос был как раз про указатель после удаления объекта, я просто не мог тогда выбрать вариант "the value of the pointer is not defined"
Жду с нетерпением апреля 2006 года, когда я возможно все-таки наберу 5.00
[/offtopic]
Re[12]: Чем может грозить удаление POD без вызова деструктор
Зависит от того, что такое SomeFunctor(args). Но well-formed это или ill-formed, а к well-/un-defined behavior это отношения не имеет.
PC>Там же тоже никакого объекта не находится? Но UB почему-то нет...
А какая связь? Где Вы во втором примере вообще увидели указатель?
PC>Или на платформах где это действительно UB, там находится еще один объект?
Реализация должна располагать объекты в памяти так, чтобы выполнялись правила адресной арифметики. Так, например, никакой объект не может быть расположен по максимальному возможному адресу. Потому, что указатель на объект, следующий за ним, при сравнении должен быть больше, чем указатель на него. И это не какая-то экзотическая реализация, а та, которой Вы пользуетесь каждый день.
Re[13]: Чем может грозить удаление POD без вызова деструктор
Здравствуйте, elcste, Вы писали:
E>Это well-defined behavior, потому что тут нет никакого lvalue-to-rvalue conversion. E>Зависит от того, что такое SomeFunctor(args). Но well-formed это или ill-formed, а к well-/un-defined behavior это отношения не имеет.
Не надо к коду придираться, я писал это для примера...
PC>>Там же тоже никакого объекта не находится? Но UB почему-то нет... E>А какая связь? Где Вы во втором примере вообще увидели указатель?
vector<int>::iterator вполне может быть реализован как указатель.
PC>>Или на платформах где это действительно UB, там находится еще один объект? E>Реализация должна располагать объекты в памяти так, чтобы выполнялись правила адресной арифметики. Так, например, никакой объект не может быть расположен по максимальному возможному адресу. Потому, что указатель на объект, следующий за ним, при сравнении должен быть больше, чем указатель на него. И это не какая-то экзотическая реализация, а та, которой Вы пользуетесь каждый день.
Какая связь? код std::copy проверяет first != last а не first < last...
Re[14]: Чем может грозить удаление POD без вызова деструктор
Pavel Chikulaev wrote:
> C>Насколько я знаю, one-past-the-last итератор должен быть валиден для > C>сравнения. Ну а как он будет сделан — неважно. > Ужас
Ага.
> [offtopic] > Я узнал почему я не добрал на Brainbench'е 0.12 Вопрос был как раз про > указатель после удаления объекта, я просто не мог тогда выбрать > вариант "the value of the pointer is not defined" > Жду с нетерпением апреля 2006 года, когда я возможно все-таки наберу 5.00 > [/offtopic]
Эхх.. А у меня скромные 4.66 — к 20-му вопросу в аське появился заказчик
и пришлось отбиваться сразу на двух фронтах