powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / virtual methods
25 сообщений из 356, страница 6 из 15
virtual methods
    #39652002
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devАга! Только класс был не "A", а "B".а что будет, если создавался класс А? флажочек заводить, что есть потомки?)) Прэлестно, как говорит Dimitry Sibiryakov ))
...
Рейтинг: 0 / 0
virtual methods
    #39652011
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychrdb_devАга! Только класс был не "A", а "B".а что будет, если создавался класс А? флажочек заводить, что есть потомки?)) Прэлестно, как говорит Dimitry Sibiryakov ))Вот так:
Код: plaintext
1.
2.
3.
4.
5.
  A* a = reinterpret_cast<A*>(std::malloc(sizeof(B)));
  if (NULL == a)
    return 1;
  new(a) A();
  delete a;

?? :)
...
Рейтинг: 0 / 0
virtual methods
    #39652012
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это называется горе от ума ))
...
Рейтинг: 0 / 0
virtual methods
    #39652016
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky, ну, это же не в "продакшн"... Просто эксперименты.
...
Рейтинг: 0 / 0
virtual methods
    #39652152
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychпринцип действия конструкций языка описан в стандарте, знание конкретной реализации не добавляет ничего нового, кроме ложной уверенности в обладании неким сакральным секретом.хмм, да, видимо, так правильнее.

a guestЗачем ты придумываешь всякую ерунду?я про то, что:
Код: plaintext
1.
2.
3.
4.
5.
{
  C c;
  vc.emplace_back(c);
  A a = c.a; // UB
}
...
Рейтинг: 0 / 0
virtual methods
    #39652163
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
CEMb, разупорись.
...
Рейтинг: 0 / 0
virtual methods
    #39652219
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, что не так?
...
Рейтинг: 0 / 0
virtual methods
    #39652235
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbegorychпринцип действия конструкций языка описан в стандарте, знание конкретной реализации не добавляет ничего нового, кроме ложной уверенности в обладании неким сакральным секретом.хмм, да, видимо, так правильнее.Угу!
Осталось объяснить это тем, кто пишет boost, компиляторы машинных кодов, потроха операционных систем, драйверы и прочим оптимизаторам.
...
Рейтинг: 0 / 0
virtual methods
    #39652422
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devпишет boost, компиляторы машинных кодов, потроха операционных систем, драйверы и прочим оптимизаторам.и как часто ты пишешь всё это? )))
пока ты по ногам себе стреляешь постоянно, несмотря на отличное владение ассемблером ;)
...
Рейтинг: 0 / 0
virtual methods
    #39652812
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devCEMbпропущено...
хмм, да, видимо, так правильнее.Угу!
Осталось объяснить это тем, кто пишет boost, компиляторы машинных кодов, потроха операционных систем, драйверы и прочим оптимизаторам.Ну-ка покажите пример из boost/потрохов операционных систем, который с точки зрения стандарта С++ приводил бы к UB...
Ну разработчики компилятора могут себе такое позволить в исходниках rtl, идущей в комплекте с конкретной версией компилятора. Потому что если в следующей версии компилятора поведение изменится, вместе с компилятором перепишут и rtl.
Да, реально видел такое в системных заголовках:
Код: plaintext
1.
#define offsetof(stype, member)  (size_t)&(((stype *)0)->member)


С точки зрения стандарта, разыменование нулевого указателя - UB. Но разработчик компилятора знает, что в данной конкретной версии так можно. А в следующей минорной версии там может оказаться
Код: plaintext
1.
#define offsetof(stype, member)  __builtin_offsetof(stype, member)

Так что в прикладном коде такие трюки нельзя, если конечно не прибивать гвоздями к конкретному релизу конкретного компилятора, потому что такое может сломаться при любом обновлении.
...
Рейтинг: 0 / 0
virtual methods
    #39652827
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Barlonerdb_devпропущено...
Угу!
Осталось объяснить это тем, кто пишет boost, компиляторы машинных кодов, потроха операционных систем, драйверы и прочим оптимизаторам.Ну-ка покажите пример из boost/потрохов операционных систем, который с точки зрения стандарта С++ приводил бы к UB...В boost есть некий вектор (boost/container/vector.hpp), видимо, типа STL-вектора.
Вот его оператор доступа по индексу:
Код: plaintext
1.
2.
3.
4.
5.
   reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
   {
      BOOST_ASSERT(this->m_holder.m_size > n);
      return this->m_holder.start()[n];
   }



В реализацию m_holder не смотрел, думаю, в этом нет необходимости. В описании complexity для push_back написано "Amortized constant time", а значит в векторе выделяется (и экспоненциально расширяется) кусок нетипизированной памяти, в котором по мере надобности создаются объекты.
А что это значит? Это значит, что массива объектов в этом куске памяти нет, а в операторе [] вектора мы видим обращение по индексу, т.е. арифметику указателей. А она, упрощённо говоря, вне массива приводит к UB: http://eel.is/c draft/expr.add#4

Вот, пример UB в boost.
...
Рейтинг: 0 / 0
virtual methods
    #39652829
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestа значит в векторе выделяется (и экспоненциально расширяется) кусок нетипизированной памяти, в котором по мере надобности создаются объекты.
А что это значит? Это значит, что массива объектов в этом куске памяти нетБуферированный new размещает объекты в уже выделенном куске памяти. Вполне штатно и определённо.
...
Рейтинг: 0 / 0
virtual methods
    #39652830
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Basil A. Sidorova guestа значит в векторе выделяется (и экспоненциально расширяется) кусок нетипизированной памяти, в котором по мере надобности создаются объекты.
А что это значит? Это значит, что массива объектов в этом куске памяти нетБуферированный new размещает объекты в уже выделенном куске памяти. Вполне штатно и определённо.Какой new?????
...
Рейтинг: 0 / 0
virtual methods
    #39652831
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BarloneНу разработчики компилятора могут себе такое позволить в исходниках rtl, идущей в комплекте с конкретной версией компилятора. Потому что если в следующей версии компилятора поведение изменится, вместе с компилятором перепишут и rtl.
Да, реально видел такое в системных заголовках:
Код: plaintext
1.
#define offsetof(stype, member)  (size_t)&(((stype *)0)->member)


С точки зрения стандарта, разыменование нулевого указателя - UB. Но разработчик компилятора знает, что в данной конкретной версии так можно. А в следующей минорной версии там может оказаться
Код: plaintext
1.
#define offsetof(stype, member)  __builtin_offsetof(stype, member)

Так что в прикладном коде такие трюки нельзя, если конечно не прибивать гвоздями к конкретному релизу конкретного компилятора, потому что такое может сломаться при любом обновлении.Во-первых, эти макродирективы не имеют никакого отношения к разыменованию по нулевому указателю, потому как разыменованием указателя называют выражения, к примеру, следующего вида:
Код: plaintext
1.
*reinterpret_cast<some_type*>(some_ptr)

в качестве lvalue или rvalue.

Во-вторых, пора бы уже разобраться, что означает так часто встречающееся в стандарте словосочетание evaluation expression!
Поясняю - результат оценки rvalue выражения ( evaluation expression ) вида:
Код: plaintext
1.
(size_t)&(((stype *)0)->member)

будет "взятие адреса" , а не доступ к объекту хранения, приводящий к UB, как некоторые до сих пор считают.
...
Рейтинг: 0 / 0
virtual methods
    #39652842
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_dev, позиция (некоторых) членов комитета такова: результат применения оператора * это lvalue. lvalue обозначает какой-то объект (битовое поле, функцию) http://eel.is/c draft/basic.lval#def:glvalue, http://eel.is/c draft/basic.lval#def:lvalue.
Т.к. по нулевому указателю объекта нет, то получается UB, т.к. что такое lvalue, которое не обозначает объекта — не определено.
В общем, с этой точки зрения, доступа к объекту (чтения, lvalue-to-rvalue conversion) не нужно, достаточно применения оператора * для наступления UB.

rdb_devВо-вторых, пора бы уже разобраться, что означает так часто встречающееся в стандарте словосочетание evaluation expression!Да. Давно пора: http://eel.is/c draft/intro.execution#def:evaluation Evaluation of an expression (or a subexpression) in general includes both value computations (including determining the identity of an object for glvalue evaluation and fetching a value previously assigned to an object for prvalue evaluation) and initiation of side effects.
Т.е. determining the identity (lvalue от применения оператора *) — это тоже evaluation of an expression.
...
Рейтинг: 0 / 0
virtual methods
    #39652850
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestКакой new?????new (буфер) тип
...
Рейтинг: 0 / 0
virtual methods
    #39652853
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Basil A. Sidorova guestКакой new?????new (буфер) типПонятно.
UB не в placement new, а в обращении с этой памятью как с содержащей массив с элементами типа T (тип элемента вектора).
...
Рейтинг: 0 / 0
virtual methods
    #39652857
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, вот именно!
Только тут надо уточнить, что подвыражение, это некоторая функционально обособленная (самостоятельная) часть выражения. Например:
Код: plaintext
1.
NULL == (ptr = malloc(sizeof(some_type)))
...
Рейтинг: 0 / 0
virtual methods
    #39652858
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestUB не в placement new, а в обращении с этой памятью как с содержащей массив с элементами типа T (тип элемента вектора).Так placement new, насколько я понимаю, именно для того и существует, чтобы получить кусок памяти и работать с ней, как с нужным типом.
...
Рейтинг: 0 / 0
virtual methods
    #39652865
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Basil A. Sidorov, ладно, объясняю на пальцах.

Пусть тип элемента вектора T = int.

Вот есть у нас кусок памяти под 4 элемента (для простоты — статический массив):
Код: plaintext
1.
unsigned char buffer[4*sizeof(int)];



Пусть в векторе 3 элемента 5, 10, 33. Их вектор создал с помощью placement new:
Код: plaintext
1.
2.
3.
new (buffer + 0*sizeof(int)) int {5};
new (buffer + 1*sizeof(int)) int {10};
new (buffer + 2*sizeof(int)) int {33};



Теперь что примерно делает оператор[]? Вот это
Код: plaintext
1.
2.
3.
4.
int& operator[](size_t n)
{
    return reinterpret_cast<int*>(buffer)[n];
}


А это точно приведёт к UB для n == 2, т.к. индексация == адресная арифметика, а она определена только в пределах массива. Никакого массива из int-ов в буфере нет.
...
Рейтинг: 0 / 0
virtual methods
    #39652870
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devТолько тут надо уточнить, что подвыражение, это некоторая функционально обособленная (самостоятельная) часть выражения.Не понимаю, к чему это.
...
Рейтинг: 0 / 0
virtual methods
    #39652873
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestладно, объясняю на пальцахЭто всё замечательно, но никто не запрещает (пере)создавать в буфере массив вместо отдельных элементов. Я, по крайней мере, таких запретов не помню.
Насколько я помню, в части выделения памяти буферированный new вообще ничего не делает. Следовательно, компилятор просто "верит", что буфер организован именно тем способом, который указан типом.
Учитывая, что в плюсах, как и в "предке" массив это указатель на начало куска памяти и (статическая) информация о размере элементов - не вижу в каком месте индексная арифметика становится неопределённой.
...
Рейтинг: 0 / 0
virtual methods
    #39652876
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Basil A. SidorovЭто всё замечательно, но никто не запрещает (пере)создавать в буфере массив вместо отдельных элементов.Лол?! Вот было в буфере 2 элемента (массив из двух элементов). Сделали push_back. Как создать массив из трёх элементов, начинающийся по тому же адресу, что массив из двух элементов (начало буфера) и сохранить значения первых двух элементов?
Basil A. SidorovСледовательно, компилятор просто "верит", что буфер организован именно тем способом, который указан типом.Мне казалось, мы здесь обсуждаем стандарт, а не во что верят компиляторы.
Basil A. SidorovУчитывая, что в плюсах, как и в "предке" массив это указательНи в плюсах, ни в предке массив это не указатель.
Basil A. Sidorovне вижу в каком месте индексная арифметика становится неопределённой.Ну с уровнем познаний типа "массив это указатель" конечно не видите. Наверное даже ссылку на стандарт (драфт) не заметили.
...
Рейтинг: 0 / 0
virtual methods
    #39652878
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestЛол?! Вот было в буфере 2 элемента (массив из двух элементов). Сделали push_back. Как создать массив из трёх элементов, начинающийся по тому же адресу, что массив из двух элементов (начало буфера) и сохранить значения первых двух элементов?Я повторю, что? насколько мне известно, placement new вообще ничего не делает с переданным ему буфером.
Поэтому ответ на ваш вопрос зависит от того, что происходит с буфером, а это, в любом случае, происходит вне placement new.
...
Рейтинг: 0 / 0
virtual methods
    #39652879
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devТолько тут надо уточнить, что подвыражение, это некоторая функционально обособленная (самостоятельная) часть выражения.Не понимаю, к чему это.К тому, что некоторые из присутствующих считают это
Код: plaintext
1.
(size_t)&(((stype *)0)->member)

самостоятельной частью выражения, которое таковым, на самом деле, не является, а всё выражение будет оценено как взятие адреса с приведением к size_t. И никакого доступа, приводящего к UB от слова "совсем"!
...
Рейтинг: 0 / 0
25 сообщений из 356, страница 6 из 15
Форумы / C++ [игнор отключен] [закрыт для гостей] / virtual methods
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]