powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / virtual methods
356 сообщений из 356, показаны все 15 страниц
virtual methods
    #39647793
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уважаемые коллеги объясните плиз

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
class A {
public :
    virtual void m() {
        std::cout << "A\n";
    }

    virtual ~A() {
        std::cout << "~A\n";
    }
};

class B : public A {

public :
    void m() override {
        std::cout << "B\n";
    }

    virtual ~B() {
        std::cout << "~B\n";
    }
};

class C : public B {

public :
    void m() override {
        std::cout << "C\n";
    }

    virtual ~C() {
        std::cout << "~C\n";
    }
};

int main() {
    A *o = new C();
    o->m();
    delete o;
}



Почему
- нет ругани на override без ключевого слова virtual ?
- почему даже не будучи virtual o->m(); все равно дергает метод класса С

Я все время думал что если метод невирутальный то A o дернет метод на классе А.

Поясните плиз тогда зачем вообще оверрайдить метод и снова делать его виртуальным - если вызов и так будет корректным.
...
Рейтинг: 0 / 0
virtual methods
    #39647795
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
semen.s.semen, давай по порядку появления в языке.

1. Сначала было только ключевое слово virtual, которое было обязательлно в базовом классе. Если сигнатура вызова в производном классе совпадала с сигнатурой виртуального метода в базовом классе, то метод был полиморфный. Но для упрощения в производном классе также можно было использовать ключевое слово virtual, чтобы легче читать код (сразу видно, что это общий интерфейс). Но тут существовала проблема: для удобства сделав в производном классе метод virtual и отнаследовавшись от этого производного класса, получали еще один полиморфизм, что не всегда нужно (в твоем случае от В к С).

2. Поэтому в С++11 это "расшили": появилось необязательное (?) ключевое слово override: теперь оно показывает общий интерфейс с базовым классом, а слово virtual- возможность иметь общий интерфейс с производным классом.
...
Рейтинг: 0 / 0
virtual methods
    #39647796
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semen,

потому что оверрайд имеет приоритет над виртуализацией
...
Рейтинг: 0 / 0
virtual methods
    #39647804
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Потому что virtual необязателен в наследнике. Если метод объявлен virtual в предке то он в наследнике тоже virtual.
...
Рейтинг: 0 / 0
virtual methods
    #39647805
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenЯ все время думал что если метод невирутальный то A o дернет метод на классе А.

У тебя метод m - виртуальный. Каким местом ты думал иначе - непонятно.
http://en.cppreference.com/w/cpp/language/override
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
virtual methods
    #39647830
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так как А объявлен с виртуальным методом, все его потомки будут иметь таблицу виртуальных функций, и там будет m(){}.

Dimitry SibiryakovУ тебя метод m - виртуальный. Каким местом ты думал иначе - непонятно.Класса В у него содержит тот самый метод, но не виртуальный, может поэтому и думал?
...
Рейтинг: 0 / 0
virtual methods
    #39647836
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Siemarglsemen.s.semen,

потому что оверрайд имеет приоритет над виртуализацией
Это вообще о чём???
...
Рейтинг: 0 / 0
virtual methods
    #39647904
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZSiemarglsemen.s.semen,

потому что оверрайд имеет приоритет над виртуализацией
Это вообще о чём???Неверно выразился - если оверрайд, то обязательно и виртуальный тоже.

Ссылка на стандарт на 2 поста выше.
...
Рейтинг: 0 / 0
virtual methods
    #39647932
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SiemarglНеверно выразился - если оверрайд, то обязательно и виртуальный тоже.

Ссылка на стандарт на 2 поста выше.
Если удалить из программы все override то суть программы не изменится.
Это просто такой static_assert для виртуальных функций.

А так все правильно
...
Рейтинг: 0 / 0
virtual methods
    #39647940
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semen, в общем-то, тебе здесь всё, более-менее, расписали, но я рекомендую тебе рассмотреть свой пример с точки зрения ABI:
1. Компилятор создает три таблицы виртуальных методов для классов A, B и C;
2. В vtable класса A у тебя указатель на "void m()" и указатель на деструктор ~A();
3. В vtable класса B у тебя переопределённый для класса B указатель на "void m()", указатель на ~A() и указатель на ~B();
4. В vtable класса C у тебя переопределённый для класса C указатель на "void m()", указатель на ~A(), указатель на ~B() и указатель на ~C();
5. Создавая экземпляр класса C, первым элементом экземпляра класса, доступным по возвращаемому оператором new указателю, является указатель на таблицу виртуальных методов класса C и никакое стандартное приведение типов его не изменит. Изменить поведение виртуальных функций экземпляра класса можно ( это грязный хак ) только изменив указатель на таблицу виртуальных методов другого класса, например на указатель к VTABLE класса A, но, во-первых, для этого необходимо иметь экземпляр класса A в качестве источника, а во-вторых, при попытке разрушить такой объект, не отработают деструкторы ~C() и ~B(), которые должны освободить ресурсы, захваченные конструкторами при создании экземпляра класса C (в твоём вырожденном примере, конструкторы классов никакие ресурсы, типа памяти из кучи, не захватывают);

Это тебе для баловства (сделай trace в отладчике):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
  typedef void (*PMethodProto)(void*);  // -- (void*) - неявный параметр this
  A* a = new A();
  C* c = new C();
  PMethodProto **pVTBL = reinterpret_cast<PMethodProto**>(c);
  (*pVTBL)[0](pVTBL);
  *pVTBL = *reinterpret_cast<PMethodProto**>(a);
  (*pVTBL)[0](pVTBL);
  delete c;

;-)
...
Рейтинг: 0 / 0
virtual methods
    #39647946
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем спасибо
...
Рейтинг: 0 / 0
virtual methods
    #39647947
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати а если у класса A виртуальный деструктор - то что будет если у B,С будут невиртуальные деструкторы ?
...
Рейтинг: 0 / 0
virtual methods
    #39647951
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenКстати а если у класса A виртуальный деструктор - то что будет если у B,С будут невиртуальные деструкторы ?Тебе надо будет дёрнуть деструктор ~B вручную из ~C. Что мешает попробовать?
...
Рейтинг: 0 / 0
virtual methods
    #39647999
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[offtop]
Ну что, форумяне, теперь вы согласитесь со мной, что для лучшего понимания - как всё работает, изучение программирования лучше начинать с ассемблера и ABI ?
...
Рейтинг: 0 / 0
virtual methods
    #39648022
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenКстати а если у класса A виртуальный деструктор - то что будет если у B,С будут невиртуальные деструкторы ?
Если в предке виртуальный, то неважно уже что там в наследниках - они уже по-любому виртуальные.
rdb_devТебе надо будет дёрнуть деструктор ~B вручную из ~C. Что мешает попробовать?
Не надо.
rdb_devНу что, форумяне, теперь вы согласитесь со мной, что для лучшего понимания - как всё работает, изучение программирования лучше начинать с ассемблера и ABI ?
Это не всем помогает, как видно
...
Рейтинг: 0 / 0
virtual methods
    #39648030
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

Спасибо
...
Рейтинг: 0 / 0
virtual methods
    #39648040
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devТебе надо будет дёрнуть деструктор ~B вручную из ~C.

Не надо.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
virtual methods
    #39648046
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Деструкторы родителя дергаются автоматически

Это я вчера еще прочитал
...
Рейтинг: 0 / 0
virtual methods
    #39648048
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenДеструкторы родителя дергаются автоматически

Это если ты уничтожаешь потомка по ссылке на потомка. При уничтожении потомка по ссылке на
родителя есть варианты.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
virtual methods
    #39648050
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakovsemen.s.semenДеструкторы родителя дергаются автоматически

Это если ты уничтожаешь потомка по ссылке на потомка. При уничтожении потомка по ссылке на
родителя есть варианты.


Расскажите поподробнее плиз
...
Рейтинг: 0 / 0
virtual methods
    #39648058
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovЭто если ты уничтожаешь потомка по ссылке на потомка. При уничтожении потомка по ссылке на
родителя есть варианты.
Если деструктор предка виртуальный то все работает как надо, неважно как удалять.
А виртуальный деструктор предка вообще-то нужно делать всегда если есть виртуальные функции.
...
Рейтинг: 0 / 0
virtual methods
    #39648073
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyЕсли в предке виртуальный, то неважно уже что там в наследниках - они уже по-любому виртуальные.
rdb_devТебе надо будет дёрнуть деструктор ~B вручную из ~C. Что мешает попробовать?Не надо.Ну, забыл я про этот нюанс! Даже не обратил внимания на подсказки IDE NetBeans - значки переопределения на полях.
...
Рейтинг: 0 / 0
virtual methods
    #39648079
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyА виртуальный деструктор предка вообще-то нужно делать всегда если есть виртуальные функции.

Да. Но не все это помнят и не все версии компиляторов об этом предупреждают.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
virtual methods
    #39648080
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenА понтов то понтов Где ты увидел, что я понтуюсь? :)
Неужели тебе был бесполезен мой пример с указателями на таблицы виртуальных методов?
...
Рейтинг: 0 / 0
virtual methods
    #39648083
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devsemen.s.semenА понтов то понтов Где ты увидел, что я понтуюсь? :)
Неужели тебе был бесполезен мой пример с указателями на таблицы виртуальных методов?

Ну ты отправил меня чего то там проверять вместо того чтобы корректно разобраться

Это я называю понтами

Я и так вчера запускал код и видел как работают деструкторы

Интересно было пообщаться с экспертами
...
Рейтинг: 0 / 0
virtual methods
    #39648084
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devНеужели тебе был бесполезен мой пример с указателями на таблицы виртуальных методов?

За это спасибо (в случае если там все корректно)
...
Рейтинг: 0 / 0
virtual methods
    #39648085
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторПочему нет ругани на override без ключевого слова virtual ?

Метод уже объявлен виртуальным в классе - предке, в дочернем классе объявление его virtual опциональное, можно написать, можно не писать. Эффект будет одинаковым.
В противовес к этому, объявление в дочернем классе метода как override убедится, что данный метод переопределяет родительский, а не объявляет новый виртуальный метод (как было бы с virtual)

автор - почему даже не будучи virtual o->m(); все равно дергает метод класса С

По той же причине. Объявление метода виртуальным ТОЛЬКО В ПРЕДКЕ достаточно, чтобы он считался виртуальным во всех иерархии классов -наследников от данного базового.

авторЯ все время думал что если метод невирутальный то A o дернет метод на классе А.


Для этого надо было убрать virtual в базовом классе, A.


авторПоясните плиз тогда зачем вообще оверрайдить метод и снова делать его виртуальным - если вызов и так будет корректным.


virtual объявляет, что данный метод виртуальный, безотносительно того, был ли он уже объявлен виртуальным в предке.
Если ты случайно ошибёшься с названием метода или его сигнатурой (например, забудешь const), то это будет другой метод уже,
и его объявление virtual в наследнике введёт новый метод, второй, в число виртуальных методов данного класса.
Убедиться, что ты ПЕРЕОПРЕДЕЛЯЕШЬ виртуальный метод базового класса с помощью модификатора virtual невозможно.
Можно только вручную проверить с базовым классом полное имя метода и сигнатуру , что они совпадают.
Для этого и введено ключевое слово, новый модификатор override. Оно позволяет именно убедится, что данный метод переопределяет виртуальный метод, объявленный в базовом классе, это значит, что у него совпадают имя и сигнатура с базовым классом и в базовом этот метод объявлен как virtual. Если это будет не так, компилятор выдаст ошибку.

Кстати, virtual переводится с английского на самом деле не как "виртуальный", а как "действительный" , "настоящий" , что очень сильно помогает понять физический смысл этого объявления.
...
Рейтинг: 0 / 0
virtual methods
    #39648087
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenНу ты отправил меня чего то там проверять вместо того чтобы корректно разобратьсяПотому и отправил...

semen.s.semenЭто я называю понтамиЛадно, пусть будут понты.
...
Рейтинг: 0 / 0
virtual methods
    #39648089
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenЗа это спасибо (в случае если там все корректно)Ты даже не проповал? :(
...
Рейтинг: 0 / 0
virtual methods
    #39648096
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devsemen.s.semenЗа это спасибо (в случае если там все корректно)Ты даже не проповал? :(

Чуть позже

сорри
...
Рейтинг: 0 / 0
virtual methods
    #39648097
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivавторПочему нет ругани на override без ключевого слова virtual ?

Метод уже объявлен виртуальным в классе - предке, в дочернем классе объявление его virtual опциональное, можно написать, можно не писать. Эффект будет одинаковым.
В противовес к этому, объявление в дочернем классе метода как override убедится, что данный метод переопределяет родительский, а не объявляет новый виртуальный метод (как было бы с virtual)

автор - почему даже не будучи virtual o->m(); все равно дергает метод класса С

По той же причине. Объявление метода виртуальным ТОЛЬКО В ПРЕДКЕ достаточно, чтобы он считался виртуальным во всех иерархии классов -наследников от данного базового.

авторЯ все время думал что если метод невирутальный то A o дернет метод на классе А.


Для этого надо было убрать virtual в базовом классе, A.


авторПоясните плиз тогда зачем вообще оверрайдить метод и снова делать его виртуальным - если вызов и так будет корректным.


virtual объявляет, что данный метод виртуальный, безотносительно того, был ли он уже объявлен виртуальным в предке.
Если ты случайно ошибёшься с названием метода или его сигнатурой (например, забудешь const), то это будет другой метод уже,
и его объявление virtual в наследнике введёт новый метод, второй, в число виртуальных методов данного класса.
Убедиться, что ты ПЕРЕОПРЕДЕЛЯЕШЬ виртуальный метод базового класса с помощью модификатора virtual невозможно.
Можно только вручную проверить с базовым классом полное имя метода и сигнатуру , что они совпадают.
Для этого и введено ключевое слово, новый модификатор override. Оно позволяет именно убедится, что данный метод переопределяет виртуальный метод, объявленный в базовом классе, это значит, что у него совпадают имя и сигнатура с базовым классом и в базовом этот метод объявлен как virtual. Если это будет не так, компилятор выдаст ошибку.

Кстати, virtual переводится с английского на самом деле не как "виртуальный", а как "действительный" , "настоящий" , что очень сильно помогает понять физический смысл этого объявления.

МастерЗив как всегда на высоте

Спасибо
...
Рейтинг: 0 / 0
virtual methods
    #39648169
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivКстати, virtual переводится с английского на самом деле не как "виртуальный", а как "действительный" , "настоящий" , что очень сильно помогает понять физический смысл этого объявления.
Сильно сомневаюсь , что такое значение у этого слова существует ))
...
Рейтинг: 0 / 0
virtual methods
    #39648174
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyMasterZivКстати, virtual переводится с английского на самом деле не как "виртуальный", а как "действительный" , "настоящий" , что очень сильно помогает понять физический смысл этого объявления.
Сильно сомневаюсь , что такое значение у этого слова существует ))
Гуглопереводчик говорит что существует
...
Рейтинг: 0 / 0
virtual methods
    #39648175
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyСильно сомневаюсь , что такое значение у этого слова существует ))Есть схожие.
...
Рейтинг: 0 / 0
virtual methods
    #39648237
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Виртуальная Реальность в таком случае Реальная Реальность? А мы в какой реальности тогда живём?
В первом значении virtual есть виртуальный, ненормальный.
Ну... можно конечно сказать it virtually not exist - его практически не существует. Когда говорим о чём то очень редком.
...
Рейтинг: 0 / 0
virtual methods
    #39648268
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По первой ссылки в гугле:

virtual

being such in power, force, or effect, though not actually or expressly such
Перевод_yandexбыть таковым в силе, силе или действии, хотя на самом деле или явно не таковым


в общем, прилагательные русского языка "действительный", "настоящий" (Теперешний, происходящий в данное время.) - вполне подходят

IMHO
...
Рейтинг: 0 / 0
virtual methods
    #39648271
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OoCcВиртуальная Реальность в таком случае Реальная Реальность? А мы в какой реальности тогда живём?
...

На вопрос, в какой мы же реальности... без поллитра не ответить. Тут и выяснится, что после водки - одна реальная, после абсента - другая. А если уж вспомнить и о других веществах изменяющих виртуальную реальность.... то не зря же, скорость это быстрые, а хмурый это хмурый )))
...
Рейтинг: 0 / 0
virtual methods
    #39648277
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevПо первой ссылки в гугле:

virtual

being such in power, force, or effect, though not actually or expressly such
Перевод_yandexбыть таковым в силе, силе или действии, хотя на самом деле или явно не таковым


в общем, прилагательные русского языка "действительный", "настоящий" (Теперешний, происходящий в данное время.) - вполне подходят

IMHO
Это то что я сказал в своем последнем предложении.

oxford dictionaryAlmost or nearly as described, but not completely or according to strict definition.

"почти то качество которое следует в последующем описании" -
авторit virtually not exist - Не существует но не совсем а почти совсем, есть надежда что всё-таки где-то существует. ИМХО К программированию это значение никак нельзя отнести
...
Рейтинг: 0 / 0
virtual methods
    #39648281
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OoCc"почти то качество которое следует в последующем описании"

В русском языке для таких вещей есть слова "подделка", "фальшивка" или "(жалкое) подобие".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
virtual methods
    #39648283
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevOoCcВиртуальная Реальность в таком случае Реальная Реальность? А мы в какой реальности тогда живём?
...

На вопрос, в какой мы же реальности... без поллитра не ответить. Тут и выяснится, что после водки - одна реальная, после абсента - другая. А если уж вспомнить и о других веществах изменяющих виртуальную реальность.... то не зря же, скорость это быстрые, а хмурый это хмурый )))
Это филосовская тема на пятничный паб. Обсуждение по мере заливкой пивом.
...
Рейтинг: 0 / 0
virtual methods
    #39648289
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovOoCc"почти то качество которое следует в последующем описании"

В русском языке для таких вещей есть слова "подделка", "фальшивка" или "(жалкое) подобие".

Неточно перевёл. Я имел ввиду синтаксическую конструкцию предложения. Мой пример обьясняет что я имел ввиду. Оксфордский словарь очень точно описывает. Понятно и без преревода.
...
Рейтинг: 0 / 0
virtual methods
    #39648294
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OoCcОксфордский словарь очень точно описывает. Понятно и без преревода.

Да хоть переводи, хоть не переводи, получается "как настоящее, только не совсем".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
virtual methods
    #39648295
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
более близкий пример:
run out of space - нет места на диске
virtually run out of space - практически нет места на диске.
...
Рейтинг: 0 / 0
virtual methods
    #39648365
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devизучение программирования лучше начинать с ассемблера и ABI ?а я всегда так делаю. В ассемблерном коде видны механизмы реализации принципов языка. Тогда некоторые вещи не надо запоминать, так как ты всегда знаешь, как внутри это устроено, и тогда не ставят в тупик всякие хитровывернутые вопросы типа "а что если из виртуального деструктора вызвать виртуальный метод, из какого класса он вызовется?"

переводи, хоть не переводитеперь это тред о переводах
...
Рейтинг: 0 / 0
virtual methods
    #39648368
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbи тогда не ставят в тупик всякие хитровывернутые вопросы типа "а что если из виртуального деструктора вызвать виртуальный метод, из какого класса он вызовется?"Встречный вопрос: "Деструктор уже разрушил состояние объекта и вызвал метод объекта - ваши действия?" - не хочется задать?
Или это слишком по еврейски?
...
Рейтинг: 0 / 0
virtual methods
    #39648392
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovВстречный вопрос: "Деструктор уже разрушил состояние объекта и вызвал метод объекта - ваши действия?" - не хочется задать?Неее, это другого сорта вопрос
Basil A. SidorovИли это слишком по еврейски?Почему это считается по-еврейски?
...
Рейтинг: 0 / 0
virtual methods
    #39648395
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov"Деструктор уже разрушил состояние объекта и вызвал метод объекта - ваши действия?"Сейчас вспомнил, что мне как-то на собеседовании задали подобный вопрос. На что я начал вести разбор полётов и задавать уточняющие вопросы, чем слегка законфузил интервьюеров.
...
Рейтинг: 0 / 0
virtual methods
    #39648427
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovCEMbи тогда не ставят в тупик всякие хитровывернутые вопросы типа "а что если из виртуального деструктора вызвать виртуальный метод, из какого класса он вызовется?"Встречный вопрос: "Деструктор уже разрушил состояние объекта и вызвал метод объекта - ваши действия?" - не хочется задать?
Или это слишком по еврейски?Такая ситуация называется "сам дурак". :)
Конечно, иногда программер способен и такое ненарочно написать. Бывает... А что будет, если объект разрушен, память от него ушла на другие нужды, а прога вызывает delete по старому указателю, в надежде, что там живой объект? Тут либо всю программу внимательно прошерстить, либо все обычные указатели заменить на смарт.
...
Рейтинг: 0 / 0
virtual methods
    #39648518
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предлагаю переводить слово "virtual", как "мнимый". В этом случае, будем получать точный смысл таких словосочетания, как:
virtual reality (мнимая реальность)
virtual memory (мнимая память - свопинг данных между оперативной памятью и ЖД)
virtual office (мнимый офис - когда работники фиг знает где, но на связи и участвуют в производственном процессе)
VPN
и т.д.
...
Рейтинг: 0 / 0
virtual methods
    #39648578
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devПредлагаю переводить слово "virtual", как "мнимый". В этом случае, будем получать точный смысл таких словосочетания, как:
virtual reality (мнимая реальность)
virtual memory (мнимая память - свопинг данных между оперативной памятью и ЖД)
virtual office (мнимый офис - когда работники фиг знает где, но на связи и участвуют в производственном процессе)
VPN
и т.д.
Применительно к компьютерам Оксфордский словарь так и обьястяет .
...
Рейтинг: 0 / 0
virtual methods
    #39648607
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще-то virtual - это и есть "недо-" "почти" настоящий.
Во всех смыслах которые тут обсуждали.
Поэтому утверждать что в применении к функциям имелось в виду "действительный", "настоящий" - это неверно, потому что смысл там обратный.
На самом деле имелось в виду "недо-функция" - заготовка функции. Это и есть суть виртуальных функций.
...
Рейтинг: 0 / 0
virtual methods
    #39648644
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky, еще "псевдо".
...
Рейтинг: 0 / 0
virtual methods
    #39648671
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TAnatoly Moskovskyпропущено...

Сильно сомневаюсь , что такое значение у этого слова существует ))
Гуглопереводчик говорит что существует

В том-то и ирония, что существует.
И "виртуальная реальность" -- это не "виртуальная", а "действительная", "реальная", т.е.
такая, что почти как настоящая.
...
Рейтинг: 0 / 0
virtual methods
    #39648672
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OoCcВиртуальная Реальность в таком случае Реальная Реальность?

Именно так.
...
Рейтинг: 0 / 0
virtual methods
    #39648678
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devBasil A. Sidorovпропущено...
Встречный вопрос: "Деструктор уже разрушил состояние объекта и вызвал метод объекта - ваши действия?" - не хочется задать?
Или это слишком по еврейски?Такая ситуация называется "сам дурак". :)
Конечно, иногда программер способен и такое ненарочно написать. Бывает... А что будет, если объект разрушен, память от него ушла на другие нужды, а прога вызывает delete по старому указателю, в надежде, что там живой объект? Тут либо всю программу внимательно прошерстить, либо все обычные указатели заменить на смарт.

Между прочим, в таком случае виртуальный метод работает 100%но нормально, как виртуальный.
Например, если в деструкторе потомка будет вызван метод предка, а тот уже вызовет виртуальный метод, переопределённый в том числе в потомке, то будет вызвана реализация из этого потомка.

Так что всё 100% ОК.
...
Рейтинг: 0 / 0
virtual methods
    #39648680
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devПредлагаю переводить слово "virtual", как "мнимый". В этом случае, будем получать точный смысл таких словосочетания, как:
virtual reality (мнимая реальность)
virtual memory (мнимая память - свопинг данных между оперативной памятью и ЖД)
virtual office (мнимый офис - когда работники фиг знает где, но на связи и участвуют в производственном процессе)
VPN
и т.д.

Не получится так просто. Это многозначное слово, и в зависимости от контекста придётся переводить по-разному.
...
Рейтинг: 0 / 0
virtual methods
    #39648682
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще насколько я понимаю в супер скоростных проектах идет отказ от исключений и виртуальных методов
...
Рейтинг: 0 / 0
virtual methods
    #39648684
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyВообще-то virtual - это и есть "недо-" "почти" настоящий.
Во всех смыслах которые тут обсуждали.
Поэтому утверждать что в применении к функциям имелось в виду "действительный", "настоящий" - это неверно, потому что смысл там обратный.
На самом деле имелось в виду "недо-функция" - заготовка функции. Это и есть суть виртуальных функций.

С чего ты это вот выдумал -- не понятно. Чем это она недо функция? Чем она заготовка ?

Суть виртуальной функции в том, что вызывается реализация исходя из динамического, реального типа данного объекта, а не в соответствии с лексическим типом объектной переменной. Т.е. вызывается ДЕЙСТВИТЕЛЬНАЯ реализация метода.
...
Рейтинг: 0 / 0
virtual methods
    #39648685
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenВообще насколько я понимаю в супер скоростных проектах идет отказ от исключений и виртуальных методов

Ты понимаешь неверно.
...
Рейтинг: 0 / 0
virtual methods
    #39648687
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivsemen.s.semenВообще насколько я понимаю в супер скоростных проектах идет отказ от исключений и виртуальных методов

Ты понимаешь неверно.

Поясни
...
Рейтинг: 0 / 0
virtual methods
    #39648690
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЧем это она недо функция? Чем она заготовка ?
Потому что где-то там, и позже (в рантайме), будет предоставлена реализация этой функции.
А само объявление где указано virtual не является реализацией, а всего лишь заготовкой.
...
Рейтинг: 0 / 0
virtual methods
    #39648696
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenMasterZivпропущено...


Ты понимаешь неверно.

Поясни

В отдельном топике.
...
Рейтинг: 0 / 0
virtual methods
    #39648702
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyА само объявление где указано virtual не является реализацией, а всего лишь заготовкой.

Оно (объявление) может быть в том числе и реализацией. Так что не понятно.
Ну ладно, это не очень важно, у каждого в голове своя модель языка, главное, чтобы написанная по этой модели программа соответствовала стандарту, а сама модель не важна.
...
Рейтинг: 0 / 0
virtual methods
    #39648709
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyMasterZivЧем это она недо функция? Чем она заготовка ?
Потому что где-то там, и позже (в рантайме), будет предоставлена реализация этой функции.
А само объявление где указано virtual не является реализацией, а всего лишь заготовкой.Кстати да! Потому как то, что называется "чисто мнимыми методами" (pure virtual methods) не имеет реализации изначально, а используются для описания интерфейсной части класса и должны иметь реализацию в инстанцирующимся потомке.
...
Рейтинг: 0 / 0
virtual methods
    #39648725
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devAnatoly Moskovskyпропущено...

Потому что где-то там, и позже (в рантайме), будет предоставлена реализация этой функции.
А само объявление где указано virtual не является реализацией, а всего лишь заготовкой.Кстати да! Потому как то, что называется "чисто мнимыми методами" (pure virtual methods) не имеет реализации изначально, а используются для описания интерфейсной части класса и должны иметь реализацию в инстанцирующимся потомке.

Это тоже не так.
pure virtual может иметь реализацию (и имеет её всегда даже если ты её не определяешь в коде).
Вы просто плохо знаете язык С++.
(я тоже фигово, не обольщайтесь)
...
Рейтинг: 0 / 0
virtual methods
    #39648742
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivОно (объявление) может быть в том числе и реализацией. Так что не понятно.
А где я сказал что не может быть реализации по умолчанию?
Но это не отменяет того что для виртуальных функций подразумевается отдельная реализация, которой в общем случае не существует на момент компиляции программы. Именно в этом их суть.
...
Рейтинг: 0 / 0
virtual methods
    #39649102
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devТакая ситуация называется "сам дурак". :)Позанудствую. Такая ситуация, да, "сам дурак" (чё я на собеседовании и сказал, но мягше).

Но речь шла про деструктор.

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

MasterZivВы просто плохо знаете язык С++.
(я тоже фигово, не обольщайтесь)Что же ты, Оби Ван, ты был нашей единственной надеждой!
...
Рейтинг: 0 / 0
virtual methods
    #39649112
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbДеструктор сам объект не разрушает, это просто метод, вызываемый перед разрушением объекта, чтобы обслужить данные внутри объекта перед разрушением. Вызывать (виртуальные) методы внутри деструктора можно, если они не используют данные объекта, уже разрушенные в этом или других деструкторах.

Результат вызова виртуального метода внутри деструктора зависит от того, в каком именно деструкторе он вызван...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
#include <iostream>

struct a {
  virtual void m() { std::cout << "a::m\n"; }
  void n() { m(); }
  virtual ~a() { n(); }
};

struct b : public a {
  virtual ~b() { n(); }
};

struct c : public b {
  virtual void m() { std::cout << "c::m\n"; }
  virtual ~c() { n(); }
};

int main() {
 a *p = new c();
 delete p;
 return 0;
}

Сначала вызывается деструктор потомка, и в нем вызывается виртуальный метод потомка. Затем вызывается деструктор предка, потомок уже разрушен, и тут вызывается метод предка.
...
Рейтинг: 0 / 0
virtual methods
    #39649174
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BarloneCEMbДеструктор сам объект не разрушает, это просто метод, вызываемый перед разрушением объекта, чтобы обслужить данные внутри объекта перед разрушением. Вызывать (виртуальные) методы внутри деструктора можно, если они не используют данные объекта, уже разрушенные в этом или других деструкторах.
Сначала вызывается деструктор потомка, и в нем вызывается виртуальный метод потомка. Затем вызывается деструктор предка, потомок уже разрушен, и тут вызывается метод предка.Поверь мне на слово, CEMb совершенно верно написал, что никакого разрушения реально не происходит - после вызова деструктора потомка, память под экземпляром класса не освобождается и деструктор предка абсолютно нормально отработает. Иными словами, объект вполне живой до тех пор, пока не отработают все деструкторы и память не будет освобождена. Задача деструктора - освободить захваченные конструктором ресурсы, но не надо освобождать деструктором конкретного класса то, что не захватывал его конструктор или методы, т.е., если конструктор или методы предка захватили память из кучи и в деструкторе предка есть реализация освобождения этих ресурсов, деструктор потомка не должен эти ресурсы освобождать, хотя и может, если соответствующие члены класса доступны ему через protected или friendly.
...
Рейтинг: 0 / 0
virtual methods
    #39649193
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devникакого разрушения реально не происходит - после вызова деструктораКроме синтаксиса есть ещё и семантика.

Да, объект, со всеми своими полями - жив и здоров.
Но, представим себе, что в одном из полей находится описатель (handle) какого-то (не)системного объекта.
Деструктор класса, в котором было объявлено это поле, может (обязан) произвести очистку ресуров и вызвать, например, close().
Вызываемый же метод может полагаться на то, что описателем находится в оперативном (открытом) состоянии. Получится нехорошо.

Проблема, разумеется, не зависит от виртуальности метода.
Но! Виртуальность добавляет сложности с пониманием того, какой именно из цепочки наследования виртуальных методов будет вызван и в каком состоянии к этому времени находится объект.

Разумеется, "погромист семи пядей во лбу" (а кто тут не умный?) всё сделает правильно, но, вроде как, промышленное программирование предполагает создание сопровождаемого кода, а не кабаллистических заклинаний.

P.S.
Вопрос в скобках был риторическим
...
Рейтинг: 0 / 0
virtual methods
    #39649235
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovДеструктор класса, в котором было объявлено это поле, может (обязан) произвести очистку ресуров и вызвать, например, close(). Вызываемый же метод может полагаться на то, что описатель находится в оперативном (открытом) состоянии. Получится нехорошо.

Проблема, разумеется, не зависит от виртуальности метода.
Но! Виртуальность добавляет сложности с пониманием того, какой именно из цепочки наследования виртуальных методов будет вызван и в каком состоянии к этому времени находится объект.Не вижу проблемы! Освободи ресурс, задай хэндлу что-то типа INVALID_HANDLE_VALUE и проверяй его в методах.
...
Рейтинг: 0 / 0
virtual methods
    #39649264
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devНе вижу проблемы!"... но умище-то я куда дену?"Освободи ресурс, задай хэндлу что-то типа INVALID_HANDLE_VALUE и проверяй его в методах."А вы на шкаф залезьте".
Не решаются, как известно, только три проблемы: смерть, налоги и желание иметь более быстрый компьютер.
Тем не менее, некоторые проблемы лучше просто не создавать .
...
Рейтинг: 0 / 0
virtual methods
    #39649270
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovНе решаются, как известно, только три проблемы: смерть, налоги и желание иметь более быстрый компьютер.
Тем не менее, некоторые проблемы лучше просто не создавать .Естественно! Поэтому, если программист написал delete с указателем на объект, а затем дёрнул метод этого объекта, то он сам создал себе проблему. Иными словами, опять получаем ситуацию "сам дурак".

Ко всему прочему, если ты создаешь экземпляр класса с каким-то public или protected методом, использующим HANDLE из private члена этого класса, то должен быть готов к тому, что кто-то, наследуя этот класс, создаст себе проблему "сам дурак" и подумать о дуракоустойчивости своей реализации, реализовав в этом методе проверку значения хэндла, а в деструкторе инициализацию хэндла в INVALID_HANDLE_VALUE после закрытия ресурса. Это нормальная практика!
...
Рейтинг: 0 / 0
virtual methods
    #39649299
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devЭто нормальная практика!Нормальная практика исключает использование виртуальных методов и в конструкторах и в деструкторах.
А вы пишите о началах проктостоматологии: "Посмотрите, как легко и непринуждённо мы подвесим у себя над головой пудовую гирю, создав несложный абажур из обычных швейных ниток!"
...
Рейтинг: 0 / 0
virtual methods
    #39649304
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorovrdb_devЭто нормальная практика!Нормальная практика исключает использование виртуальных методов и в конструкторах и в деструкторах.
А вы пишите о началах проктостоматологии: "Посмотрите, как легко и непринуждённо мы подвесим у себя над головой пудовую гирю, создав несложный абажур из обычных швейных ниток!"
Мне это не очень понятно.

Описанный Вами сценарий с закрытием файлов - одинаков, что для виртуальных/что для обычных методов. Не говоря уже о том, что это не столько сценарий, сколько описание банальной ошибки (при это даже не кодирования, а скорее documentation баг)

Запрет на вызов виртуальных методов в конструкторе/диструкторе/виртуальном диструкторе.... для меня как-то совсем не очевиден. А если у меня достаточно сложный алгоритм инициализации/убийства и я хочу дать возможность в потомках переопределить поведение "в середине" данного алгоритма? Если без виртуальных методов, то это только переопределять целиком конструктор/диструктор и copy-past... ерунда какая-то получается.
...
Рейтинг: 0 / 0
virtual methods
    #39649305
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov, какая разница - виртуальный метод или не виртуальный, если программист написал delete, деструктор освободил ресурс, а потом программа дёргает метод, использующий уже освобождённый ресурс? От такой дури спасут только смарт-указатели.
...
Рейтинг: 0 / 0
virtual methods
    #39649309
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevЕсли без виртуальных методов, то это только переопределять целиком конструктор/диструктор и copy-past... ерунда какая-то получается.Невиртуальный деструктор предка можно из деструктора потомка и ручками дёрнуть - тоже не проблема...
...
Рейтинг: 0 / 0
virtual methods
    #39649318
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devLeonid KudryavtsevЕсли без виртуальных методов, то это только переопределять целиком конструктор/диструктор и copy-past... ерунда какая-то получается.Невиртуальный деструктор предка можно из деструктора потомка и ручками дёрнуть - тоже не проблема...

переопределить поведение " в середине " данного алгоритма


или плодить callback'и, что бред. Или virtual методы, просто понятно и красиво.

p.s.
Сам пытаюсь в конструкторах/деструкторах иметь минимум логики. Но чисто гипотетически, вполне можно представить необходимость такого
...
Рейтинг: 0 / 0
virtual methods
    #39649326
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevА если у меня достаточно сложный алгоритм инициализации/убийства и я хочуГоре от ума.

Если вы создаёте избыточно сложную конструкцию, то рано или поздно вы перехитрите самого себя.
Или даже не вы, а человек, который унаследовался от вашего объекта и, не подумав (не дочитав документацию), переопределил виртуальный метод.

В конструкторах виртуальный метод может вызвать метод (далёкого) потомка до вызова конструктора этого потомка.
В лучшем случае вы будете манипулировать неинициализированными полями, в худшем - просто мусором.
Аналогично, в деструкторах, виртуальный метод потомка может манипулировать объектом, для предка которого уже вызван деструктор.

Поэтому - всё как обычно: вместо того, чтобы бороться с последствиями проблемы, проблему просто не надо создавать.
...
Рейтинг: 0 / 0
virtual methods
    #39649337
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov...
В конструкторах виртуальный метод может вызвать метод (далёкого) потомка до вызова конструктора этого потомка.
В лучшем случае вы будете манипулировать неинициализированными полями, в худшем - просто мусором.
Аналогично, в деструкторах, виртуальный метод потомка может манипулировать объектом, для предка которого уже вызван деструктор.

Поэтому - всё как обычно: вместо того, чтобы бороться с последствиями проблемы, проблему просто не надо создавать.
Спасибо за разъяснения.
...
Рейтинг: 0 / 0
virtual methods
    #39649358
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovВ конструкторах виртуальный метод может вызвать метод (далёкого) потомка до вызова конструктора этого потомка.
В лучшем случае вы будете манипулировать неинициализированными полями, в худшем - просто мусором.
Аналогично, в деструкторах, виртуальный метод потомка может манипулировать объектом, для предка которого уже вызван деструктор.Не может. Ни в конструкторе, ни в деструкторе.
...
Рейтинг: 0 / 0
virtual methods
    #39649362
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovВ конструкторах виртуальный метод может вызвать метод (далёкого) потомка до вызова конструктора этого потомка.неа, не может. конструктор предка не знает, есть у него потомок или нет. Он вызовет свою реализацию метода, если она есть или упадёт с криком "pure virtual function call". если повезёт, а если не повезёт, то предстоят мучительные часы медитации над вопросом почему код, который я написал - вообще не вызывается) . Ну а в деструкторе - обратная проблема
...
Рейтинг: 0 / 0
virtual methods
    #39649370
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вон в стандарте написано (раздел 12.7):Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2). When a virtual function is called directly or indirectly from a constructor or from a destructor, including during the construction or destruction of the class’s non-static data members, and the object to which the call applies is the object (call it x) under construction or destruction, the function called is the final overrider in the constructor’s or destructor’s class and not the one overriding it in a more-derived class.
...
Рейтинг: 0 / 0
virtual methods
    #39649383
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таким образом, комитет по стандартизации озадачился проблемой настолько, что таблица виртуальных методов специальном образом "хачится" в конструкторах/деструкторах, чтобы, не дай бог, не дёрнуть метод из иерархии предков.

Кто там чего говорил про безопасность и понятность вызова виртальных методов в фазе инициализации и разрушения объектов?
...
Рейтинг: 0 / 0
virtual methods
    #39649406
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovТаким образом, комитет по стандартизации озадачился проблемой настолько, что таблица виртуальных методов специальном образом "хачится" в конструкторах/деструкторах, чтобы, не дай бог, не дёрнуть метод из иерархии предков.
Ну в стандарте напрямую таблица виртуальных методов вообще не упоминается. Но так то да, в конструкторах и деструкторах помимо вашего кода есть еще немножко: установка указателя vmt, вызов конструктора/деструктора предка.
...
Рейтинг: 0 / 0
virtual methods
    #39649417
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovТаким образом, комитет по стандартизации озадачился проблемой настолько, что таблица виртуальных методов специальном образом "хачится" в конструкторах/деструкторах, чтобы, не дай бог, не дёрнуть метод из иерархии предков.Только не таблица, а указатель на эту таблицу - первый элемент экземпляра класса, на который указывает this. Сама таблица может преспокойно жить в read-only памяти. Иными словами, перед вызовом конструктора/деструктора компилятор вставляет код, меняющий указатель на таблицу виртуальных методов соответствующего класса.
...
Рейтинг: 0 / 0
virtual methods
    #39649420
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov....таблица виртуальных методов специальном образом "хачится" в конструкторах/деструкторах, чтобы, не дай бог, не дёрнуть метод из иерархии предков....

есть подозрение, что "хачить" ее приходится по причине множественного наследования (где AFAIK тоже есть слова virtual для предков)

rdb_dev....Иными словами, перед вызовом конструктора/деструктора компилятор вставляет код, меняющий указатель на таблицу виртуальных методов соответствующего класса.

Спасибо. Лично я таких подробностей не знал.
...
Рейтинг: 0 / 0
virtual methods
    #39649427
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для множественного наследования есть более-менее нетривиальные правила, которые можно запомнить и научиться применять: в конце-концов, мы знаем, на что идём.

Для виртуальных методов в конструкторах/деструкторах "знать" - просто невозможно.
Или вы будете работать с полусозданными (полуразрушенными) объектами или вы изменяете механизм виртуализации вызова методов в конструкторах и деструкторах.

Комитет выбрал второй вариант, хотя для этого разработчикам компиляторов приходится добавлять в конструкторы и деструкторы больше служебного кода.
...
Рейтинг: 0 / 0
virtual methods
    #39649431
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevСпасибо. Лично я таких подробностей не знал.Проверяется несложно - выставляются точки останова в конструкторах и деструкторах по всей иерархии наследования, а в отладчике выставляется наблюдение за (size_t)*this
...
Рейтинг: 0 / 0
virtual methods
    #39649435
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov, ну ведь кто-то должен проинициализировать указатель на vmt. Вот он в конструкторе и инициализируется. Тут все вполне логично. Сконструировали предков, выставили адрес vmt, потом выполнили пользовательский код.
В деструкторе да, повторное выставление этого указателя - как бы "лишний" код. Ну тут видимо по соображениям симметрии.
...
Рейтинг: 0 / 0
virtual methods
    #39649436
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovКомитет выбрал второй вариант, хотя для этого разработчикам компиляторов приходится добавлять в конструкторы и деструкторы больше служебного кода.Я тебе больше скажу - некоторые компиляторы добавляют в таблицу виртуальных методов указатели на служебные ВИРТУАЛЬНЫЕ конструкторы. :)
...
Рейтинг: 0 / 0
virtual methods
    #39649460
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BarloneBasil A. Sidorov, ну ведь кто-то должен проинициализировать указатель на vmt. Вот он в конструкторе и инициализируется. Тут все вполне логично.Это всё понятно.

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

Но, видимо, эстеты от программирования представляют достаточную опасность, чтобы в стандарте заложились на максимально безопасное поведение, не ограничиваясь простым предупреждением о неопределённом поведении.
...
Рейтинг: 0 / 0
virtual methods
    #39649464
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovНо, видимо, эстеты от программирования представляют достаточную опасность, чтобы в стандарте заложились на максимально безопасное поведение, не ограничиваясь простым предупреждением о неопределённом поведении.Потому я и настаиваю на дуракоустойчивой реализации методов, а ты мне - проктостоматология, проктостоматология!...
...
Рейтинг: 0 / 0
virtual methods
    #39649471
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devпроктостоматология, проктостоматология!... У вас есть другое определение для использования виртуальных методах в конструкторах и деструкторах?
...
Рейтинг: 0 / 0
virtual methods
    #39649473
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov, виртуальные методы не причем, если программист сначала пишет delete ptr, а потом ptr->method(), когда ресурсы уже освобождены, а память кучи из под объекта уже выделена на что-то другое.
...
Рейтинг: 0 / 0
virtual methods
    #39649650
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevСпасибо. Лично я таких подробностей не знал.Вот поэтому полезно смотреть, как работает с++ код под ассемблером :)
...
Рейтинг: 0 / 0
virtual methods
    #39650156
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbВот поэтому полезно смотреть, как работает с++ код под ассемблером :)ага, на каждой версии компилятора, используемого в разработке в текущий момент, искать отличия от предыдущих версий, медитировать над ними... ведь работа не х.., стояла и будет стоять)))
...
Рейтинг: 0 / 0
virtual methods
    #39650218
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devнекоторые компиляторы добавляют в таблицу виртуальных методов указатели на служебные ВИРТУАЛЬНЫЕ конструкторы. :)Может ты с деструкторами путаешь? Принеси пример.
...
Рейтинг: 0 / 0
virtual methods
    #39650439
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вангую что сейчас прозвучит слово борланд ))
...
Рейтинг: 0 / 0
virtual methods
    #39650491
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyВангую что сейчас прозвучит слово борланд ))Не прозвучит, потому что я не помню где наблюдал служебные виртуальные конструкторы. Вполне возможно, что и у Борланда.
...
Рейтинг: 0 / 0
virtual methods
    #39650820
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychага, на каждой версии компилятора, используемого в разработке в текущий момент, искать отличия от предыдущих версий, медитировать над ними... ведь работа не х.., стояла и будет стоять)))ну когда-то же учиться надо. Это не 100 лет назад, когда один раз в 16 лет научился быть плотником, и потом 100 лет ничего не меняется. Тут совсем другая кухня, надо мыслить стратегически
День потерял (на изучение новых плюсов) зато потом за 5 минут долетел.
...
Рейтинг: 0 / 0
virtual methods
    #39651008
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbДень потерял (на изучение новых плюсов) зато потом за 5 минут долетел.для этого стандарт надо читать, или страуструпа, а не в ассемблер лазить.
...
Рейтинг: 0 / 0
virtual methods
    #39651061
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devBarloneпропущено...
Сначала вызывается деструктор потомка, и в нем вызывается виртуальный метод потомка. Затем вызывается деструктор предка, потомок уже разрушен, и тут вызывается метод предка.Поверь мне на слово, CEMb совершенно верно написал, что никакого разрушения реально не происходит - после вызова деструктора потомка, память под экземпляром класса не освобождается и деструктор предка абсолютно нормально отработает. Иными словами, объект вполне живой до тех пор, пока не отработают все деструкторы и память не будет освобождена. Задача деструктора - освободить захваченные конструктором ресурсы, но не надо освобождать деструктором конкретного класса то, что не захватывал его конструктор или методы, т.е., если конструктор или методы предка захватили память из кучи и в деструкторе предка есть реализация освобождения этих ресурсов, деструктор потомка не должен эти ресурсы освобождать, хотя и может, если соответствующие члены класса доступны ему через protected или friendly.

Да, всё так, только "объект вполне живой" -- не совсем верное определение. Точнее, совсем неверное.
У объекта в процессе разрушения меняется тип, он их последнего наследника становится сначала предпоследним, потом пред-предпоследним наследником, и так далее, ... потом -- вторым предком, потом --первым предком, потом только разрушается.

Т.е. объект "умирает" частями, от наследников к родителям. В обратном порядке к такому же "рождению" по частям от родителей к наследникам.

Т.е. "объект вполне живой" -- неверно , определённые подобъекты всего объекта ещё живы, но какие-то подобъекты уже умерли. Для тех, где отработал деструктор уже -- они мертвы, где ещё нет -- являются валидными объектами.
...
Рейтинг: 0 / 0
virtual methods
    #39651063
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devAnatoly MoskovskyВангую что сейчас прозвучит слово борланд ))Не прозвучит, потому что я не помню где наблюдал служебные виртуальные конструкторы. Вполне возможно, что и у Борланда.

Ага, Борланд и Виртуальные Констукторы! ЕЕЕЕ!
У Борланд даже виртуальные статические методы могут быть и даже виртуальные глобальные фукнции!
Я верю всему!
...
Рейтинг: 0 / 0
virtual methods
    #39651092
Фотография ну я
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivrdb_devпропущено...
Не прозвучит, потому что я не помню где наблюдал служебные виртуальные конструкторы. Вполне возможно, что и у Борланда.

Ага, Борланд и Виртуальные Констукторы! ЕЕЕЕ!
У Борланд даже виртуальные статические методы могут быть и даже виртуальные глобальные фукнции!
Я верю всему!
И они для совместимости с раскладкой дельфийских виртуальных конструкторов объявляемых в registered class.
По имени класса в виде строки получаешь описатель класса (указатель на специальный объект) с виртуальными функциями, среди которых функция конструирования экземпляра объекта.
Она в классе класса (в С++ прямого аналога нет) виртуальная, но для экземпляра - конструктор.
Да, и static virtual есть)))) И оно реально есть и работает ))) Для взятия указателя на функцию которая static virtual берется таблица на указатели не от объекта, а от класса класса (то что в дельфи class of). Берем по имени класса описатель, а у него - да, виртуальная функция и она применяется не к экземпляру класса, а к текущему классу, будучи объявленной в базовом классе )))).

Если я чего-то не знаю - это не значит что этого нет. Это значит что я этого не знаю.
...
Рейтинг: 0 / 0
virtual methods
    #39651168
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivДа, всё так, только "объект вполне живой" -- не совсем верное определение. Точнее, совсем неверное.
У объекта в процессе разрушения меняется тип, он их последнего наследника становится сначала предпоследним, потом пред-предпоследним наследником, и так далее, ... потом -- вторым предком, потом --первым предком, потом только разрушается.

Т.е. объект "умирает" частями, от наследников к родителям. В обратном порядке к такому же "рождению" по частям от родителей к наследникам.

Т.е. "объект вполне живой" -- неверно , определённые подобъекты всего объекта ещё живы, но какие-то подобъекты уже умерли. Для тех, где отработал деструктор уже -- они мертвы, где ещё нет -- являются валидными объектами.Так-то оно так, но пока память из под объекта не перевыделена и не перезатёрта, этот "зомби" может казаться вполне живым и даже корректно помахивать невиртуальными членами. :)
...
Рейтинг: 0 / 0
virtual methods
    #39651295
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devТак-то оно так, но пока память из под объекта не перевыделена и не перезатёрта, этот "зомби" может казаться вполне живым и даже корректно помахивать невиртуальными членами. :)только вызвать их при разрушении ( без грязных хаков ) нельзя
...
Рейтинг: 0 / 0
virtual methods
    #39651333
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorych, да ну какие грязные хаки при вызове невиртуальных методов? Просто дёрнуть метод по указателю и всё.
...
Рейтинг: 0 / 0
virtual methods
    #39651439
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychCEMbДень потерял (на изучение новых плюсов) зато потом за 5 минут долетел.для этого стандарт надо читать, или страуструпа, а не в ассемблер лазить.Знания без понимания принципов и механик ведут на тёмную сторону -_-
Когда ты что-то просто знаешь - ты можешь забыть, или перепутать что-то. Когда ты понимаешь принципы действия, ты можешь получить правильные знания в любой момент сам.
...
Рейтинг: 0 / 0
virtual methods
    #39651440
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivДа, всё так, только "объект вполне живой" -- не совсем верное определение. Точнее, совсем неверное.я просто хотел сказать, что в деструкторе надо действовать аккуратно: если (зачем-то) нужно, то обращаться только к тем данным, которые ещё не разрушены.

Кстати, такая же, примерно, ситуация с объектами после std::move - формально их трогать нельзя.
...
Рейтинг: 0 / 0
virtual methods
    #39651441
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
CEMbКстати, такая же, примерно, ситуация с объектами после std::move - формально их трогать нельзя.Зачем ты придумываешь всякую ерунду?
...
Рейтинг: 0 / 0
virtual methods
    #39651715
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devegorych, да ну какие грязные хаки при вызове невиртуальных методов? Просто дёрнуть метод по указателю и всё.указатель указывает на тип, в котором нет этих методов, помним об этом? мы в деструкторе предка сейчас.
...
Рейтинг: 0 / 0
virtual methods
    #39651725
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbКогда ты понимаешь принципы действия, ты можешь получить правильные знания в любой момент сам.принцип действия конструкций языка описан в стандарте, знание конкретной реализации не добавляет ничего нового, кроме ложной уверенности в обладании неким сакральным секретом. Вон, в соседнем топике рубятся уже 3 страницы о смысле инструкции push rax, чем это им помогает в понимании С++ я не знаю))
...
Рейтинг: 0 / 0
virtual methods
    #39651743
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbКстати, такая же, примерно, ситуация с объектами после std::move - формально их трогать нельзя.
std::move ничего не делает с объектами. А вот move-ctor или move-assignment-operator - да, делают.
...
Рейтинг: 0 / 0
virtual methods
    #39651745
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorych, невиртуальные методы есть всегда. Рассмотри такой вариант:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
struct B;

struct A
{
  virtual ~A();
};

struct B : public A
{
  int m;

  B()
  {
    this->m = -1;
    printf("m = %i\r\n", this->m);
  }

  int set(int src)
  {
    this->m = src;
  }
};

A::~A()
{
  B & b = *reinterpret_cast<B*>(this);
  b.set(0);
  printf("m = %i\r\n", b.m);
}
...
Рейтинг: 0 / 0
virtual methods
    #39651750
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychВон, в соседнем топике рубятся уже 3 страницы о смысле инструкции push rax, чем это им помогает в понимании С++ я не знаю))Где ты в 4-х комментариях три страницы разглядел? Про назначение push rax в примере уже давно выяснили.
...
Рейтинг: 0 / 0
virtual methods
    #39651764
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devegorych, невиртуальные методы есть всегда. Рассмотри такой вариант:
Код: plaintext
1.
2.
3.
4.
5.
6.
A::~A()
{
  B & b = *reinterpret_cast<B*>(this); // а вот и грязный хак
  b.set(0);
  printf("m = %i\r\n", b.m);
}


что будет, если я так напишу, подумай:
Код: plaintext
1.
2.
A *a = new A;
delete a;

??
...
Рейтинг: 0 / 0
virtual methods
    #39651765
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devegorychВон, в соседнем топике рубятся уже 3 страницы о смысле инструкции push rax, чем это им помогает в понимании С++ я не знаю))Где ты в 4-х комментариях три страницы разглядел? Про назначение push rax в примере уже давно выяснили.это был сарказм)))
...
Рейтинг: 0 / 0
virtual methods
    #39651769
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devegorych, невиртуальные методы есть всегда. Рассмотри такой вариант:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
struct B;

struct A
{
  virtual ~A();
};

struct B : public A
{
  int m;

  B()
  {
    this->m = -1;
    printf("m = %i\r\n", this->m);
  }

  int set(int src)
  {
    this->m = src;
  }
};

A::~A()
{
  B & b = *reinterpret_cast<B*>(this);
  b.set(0);
  printf("m = %i\r\n", b.m);
}

Ну да, выстрелить себе в ногу можно всегда. Примерно с тем же успехом можно сделать и так:
Код: plaintext
1.
2.
3.
4.
  double x;
  B & b = *reinterpret_cast<B*>(&x);
  b.set(0);
  printf("m = %i\r\n", b.m);
...
Рейтинг: 0 / 0
virtual methods
    #39651831
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorych
Код: plaintext
1.
2.
3.
4.
5.
6.
A::~A()
{
  B & b = *reinterpret_cast<B*>(this); // а вот и грязный хак
  b.set(0);
  printf("m = %i\r\n", b.m);
}

Это не "грязный", а "чистый" хак. Грязный, это когда ты, например, у экземпляра класса сам меняешь указатель на vtable.

egorychчто будет, если я так напишу, подумай:
Код: plaintext
1.
2.
A *a = new A;
delete a;

??Именно так я и тестировал! Всё прекрасно отработает. :) Ведь деструктор отрабатывает до того, как память будет освобождена.
...
Рейтинг: 0 / 0
virtual methods
    #39651833
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BarloneНу да, выстрелить себе в ногу можно всегда. Примерно с тем же успехом можно сделать и так:
Код: plaintext
1.
2.
3.
4.
  double x;
  B & b = *reinterpret_cast<B*>(&x);
  b.set(0);
  printf("m = %i\r\n", b.m);

Речь не о суициде, а о том, что по типизированному указателю невиртуальные методы работают при любых обстоятельствах.
...
Рейтинг: 0 / 0
virtual methods
    #39651846
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devИменно так я и тестировал! Всё прекрасно отработает. :)
Жесть
...
Рейтинг: 0 / 0
virtual methods
    #39651859
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barlone, кстати, твой пример прекрасно будет работать, если вручную выставить указатель на vtable.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
  typedef void (B::* B_func)();
  B * tmp = new B();
  B_func* vtbl = *reinterpret_cast<B_func**>(tmp);
  delete tmp;

  double x;
  *reinterpret_cast<B_func**>(&x) = vtbl;
  B & b = *reinterpret_cast<B*>(&x);
  b.set(0);
  printf("m = %i\r\n", b.m);
...
Рейтинг: 0 / 0
virtual methods
    #39651875
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Забыл дописать - на x86_32 при выравнивании структур на 4 байта.
...
Рейтинг: 0 / 0
virtual methods
    #39651990
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskyrdb_devИменно так я и тестировал! Всё прекрасно отработает. :)
ЖестьАга! Только класс был не "A", а "B".
...
Рейтинг: 0 / 0
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
virtual methods
    #39652880
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Не понимаю, к чему это.К тому, что некоторые из присутствующих считают это
Код: plaintext
1.
(size_t)&(((stype *)0)->member)

самостоятельной частью выражения, которое таковым, на самом деле, не является, а всё выражение будет оценено как взятие адреса с приведением к size_t. И никакого доступа, приводящего к UB от слова "совсем"!Т.е. UB может возникать только в полных выражениях, а в подвыражениях UB не бывает?
...
Рейтинг: 0 / 0
virtual methods
    #39652884
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Basil A. SidorovЯ повторю, что? насколько мне известно, placement new вообще ничего не делает с переданным ему буфером.А зачем он нужен, если ничего не делает? Можно не вызвать его тогда...
Basil A. SidorovПоэтому ответ на ваш вопрос зависит от того, что происходит с буфером, а это, в любом случае, происходит вне placement new.Я рассчитывал на код, который создаёт массив из трёх элементов поверх массива из двух, при этом первые 2 элемента будут содержать те же значение, что и первые 2 элемента старого массива. И это без копирования (иначе откуда возьмётся amortized constant, если мы будем всё копировать?).
Было бы забавно увидеть попытки написать такой код.
...
Рейтинг: 0 / 0
virtual methods
    #39652886
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestА зачем он нужен, если ничего не делает?Вроде, должно быть очевидно, что placement new позволяет превратить указатель на массив байт в типированный указатель.
Цена вопроса - внешнее управление существованием буфера и ручная работа с конструкторами и деструкторами типа.
...
Рейтинг: 0 / 0
virtual methods
    #39652887
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Basil A. SidorovВроде, должно быть очевидно, что placement new позволяет превратить указатель на массив байт в типированный указатель.Чем он тогда отличается от каста?
...
Рейтинг: 0 / 0
virtual methods
    #39652889
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestсамостоятельной частью выражения, которое таковым, на самом деле, не является, а всё выражение будет оценено как взятие адреса с приведением к size_t. И никакого доступа, приводящего к UB от слова "совсем"!Т.е. UB может возникать только в полных выражениях, а в подвыражениях UB не бывает?[/quot]Я же, вроде, до этого ясно написал, про подвыражения...
Конечно, UB по нулевому указателю может быть и в подвыражении. Простой пример:
Код: plaintext
1.
2.
3.
typedef void (A::* A_func)();
A_func** a = NULL;
A_func f = **a;

Неопределенное поведение выделено и является подвыражением rvalue выражения.
Кстати, еще хотелось бы ответить, что по своей сути, доступ по указателю (void*)0 не является ошибкой, так как в нулевом адресе адресного пространства процессора нет ничего неопределенного и в данном случае UB лишь условность стандарта и компилятора на его основе.
...
Рейтинг: 0 / 0
virtual methods
    #39652894
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devеще хотелось бы ответить,...отметить
:)
...
Рейтинг: 0 / 0
virtual methods
    #39652895
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_dev, ок.

Так в конце-концов что делать с тем, что lvalue по определению обозначает объект, нулевой указатель по определению не указывает ни на какой объект, а результат оператора * это lvalue? Какой объект обозначает это lvalue, если оно применено к нулевому указателю?
...
Рейтинг: 0 / 0
virtual methods
    #39652898
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestЧем он тогда отличается от каста?Тем, что это частный случай переопределения оператора "operator new", который работает там, где не работает преобразование void* к нужному типу.
...
Рейтинг: 0 / 0
virtual methods
    #39652899
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Basil A. Sidorov где не работает преобразование void* к нужному типу.А можно пример где оно не работает?
...
Рейтинг: 0 / 0
virtual methods
    #39652900
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_dev, ок.
Так в конце-концов что делать с тем, что lvalue по определению обозначает объект,обозначает любую разыменованную область памяти.

a guestнулевой указатель по определению не указывает ни на какой объект,Не надо путать nullptr и NULL.
При использовании доступа по указателю NULL ((void*)0) компилятор хоть и выкинет предупреждение UB, но соберёт вполне рабочий код, так как он понятия не имеет, что именно пишет программист - прикладное ПО или же какой-нибудь legacy загрузчик ОС из MBR или BR, который грузится в 0000:7c

a guestа результат оператора * это lvalue?не обязательно... Это может быть и prvalue:
Код: plaintext
1.
2.
3.
int *pa, *pb;
int a, b = 20;
*a = *b  // prvalue of int


a guestКакой объект обозначает это lvalue, если оно применено к нулевому указателю?Какой тип указателя используешь, такой объект там и будет подразумеваться компилятором.
Что у нас там в далёком прошлом под DOS'ом располагалось в самом начале адресного пространства процессора Intel 8086? Таблица векторов прерываний (функций BIOS и DOS вызываемых машинной командой int)?
А что располагается сейчас в адресном пространстве пользовательского процесса Windows? 64кБ read-only памяти, каждый байт, которой, проинициализирован значением 0x00?
...
Рейтинг: 0 / 0
virtual methods
    #39652901
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestВ 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.
Нет там никакого UB в этом коде.
UB будет если юзер обратится к индексу за пределами массива. Это будут проблемы юзера, потому что в доке по вектору прямо написано при каких условиях можно [].
...
Рейтинг: 0 / 0
virtual methods
    #39652902
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestА можно пример где оно не работает?
Код: sql
1.
Тип переменная = new(буфер) Тип

Тип это примитив или объект, а не указатель на примитив или объект.
...
Рейтинг: 0 / 0
virtual methods
    #39652904
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyНет там никакого UB в этом коде.Очевидно, в самом-по-себе коде буста UB нет, ведь это библиотека. UB будет когда юзер вызовет код из буста.
Anatoly MoskovskyUB будет если юзер обратится к индексу за пределами массива.Там нет массива, а обращаются памятью так, как будто он там есть.
Anatoly MoskovskyЭто будут проблемы юзера, потому что в доке по вектору прямо написано при каких условиях можно [].А из того, что написано в стандарте следует, что больше, чем с n == 0 оператор[] вызывать нельзя, даже если size > 1.
...
Рейтинг: 0 / 0
virtual methods
    #39652908
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestrdb_dev, ок.
Так в конце-концов что делать с тем, что lvalue по определению обозначает объект,обозначает любую разыменованную область памяти.Ложь. A glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function. (An lvalue is a glvalue that is not an xvalue.)

rdb_deva guestнулевой указатель по определению не указывает ни на какой объект,Не надо путать nullptr и NULL.При преобразовании к типу указателя обе этих сущности породят указатель с null pointer value. Я не путаю, мне лень различать, как получилось null pointer value. ( http://eel.is/c draft/basic.compound#def:value,null_pointer )

rdb_deva guestа результат оператора * это lvalue?не обязательно... Это может быть и prvalue:Опять ложь. http://eel.is/c draft/expr.unary.op#1: The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.
...
Рейтинг: 0 / 0
virtual methods
    #39652911
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Basil A. Sidorova guestА можно пример где оно не работает?
Код: sql
1.
Тип переменная = new(буфер) Тип

Тип это примитив или объект, а не указатель на примитив или объект.Стоит пробовать скомпилировать подобное, прежде чем предъявлять.
...
Рейтинг: 0 / 0
virtual methods
    #39652917
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestобозначает любую разыменованную область памяти.Ложь. A glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function. (An lvalue is a glvalue that is not an xvalue.)[/quot]И в чем же ложь? В том, что моё определение не соответствует дословно определению стандарта?
Где располагаются объекты, битовые поля или код функций?

a guestrdb_devНе надо путать nullptr и NULL.При преобразовании к типу указателя обе этих сущности породят указатель с null pointer value. Я не путаю, мне лень различать, как получилось null pointer value. ( http://eel.is/c draft/basic.compound#def:value,null_pointer )На nullptr накладывается больше ограничений - его нельзя напрямую привести к целочисленным типам.

a guestrdb_devне обязательно... Это может быть и prvalue:Опять ложь. http://eel.is/c draft/expr.unary.op#1: The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.Ну так одним из частных случаев prvalue и есть нереферальный результат lvalue-to-rvalue. Как ты стандарт читал? Смотрим в книгу - видим фигу? Или ты считаешь, что в соответствии со стандартом такая запись:
Код: plaintext
1.
*a = *b;

"неправомерна" :)?
...
Рейтинг: 0 / 0
virtual methods
    #39652918
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestОчевидно, в самом-по-себе коде буста UB нет
Что и требовалось доказать.
А то что кто-то обращается к индексу за пределами текущего выделения вектора то это его проблемы, потому что нарушение предусловий вызова функции это и есть UB.
Не надо с больной головы переводить на буст ))
...
Рейтинг: 0 / 0
virtual methods
    #39652920
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_deva guestrdb_devобозначает любую разыменованную область памяти.Ложь. A glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function. (An lvalue is a glvalue that is not an xvalue.)И в чем же ложь? В том, что моё определение не соответствует дословно определению стандарта?
Где располагаются объекты, битовые поля или код функций?Давай-ка я перевормулирую поточнее:
lvalue - любая разыменованная область оперативного хранения.
Так сойдёт? Или опять скажешь, что "не соответствует стандарту"? :)
...
Рейтинг: 0 / 0
virtual methods
    #39652921
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devИ в чем же ложь? В том, что моё определение не соответствует дословно определению стандарта?Да. Это раздел про C++. Доморощенным определениям тут вряд ли место. А то так каждый будет выдумывать всё, что ему лично в данный момент удобно.

rdb_deva guestrdb_devНе надо путать nullptr и NULL.При преобразовании к типу указателя обе этих сущности породят указатель с null pointer value. Я не путаю, мне лень различать, как получилось null pointer value. ( http://eel.is/c draft/basic.compound#def:value,null_pointer )На nullptr накладывается больше ограничений - его нельзя напрямую привести к целочисленным типам.Это, безусловно, играет ключевую роль при преобразовании nullptr к указателю.

rdb_devНу так одним из частных случаев prvalue и есть нереферальный результат lvalue-to-rvalueМы обсуждали value category оператора *.
Я как бы в курсе, что результат lvalue-to-rvalue conversion это prvalue.

rdb_devКак ты стандарт читал?А ты? Что в словосочетании "the result is an lvalue" тебе не ясно?
...
Рейтинг: 0 / 0
virtual methods
    #39652922
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskya guestОчевидно, в самом-по-себе коде буста UB нет
Что и требовалось доказать.Ни в каком коде никакой библиотеки UB нет. UB будет в программе, которая её вызовет. Это всё, что я хотел сказать. Очевидная вещь.
Я думаю, ты как-то не так интерпретировал эти мои слова.
Anatoly MoskovskyА то что кто-то обращается к индексу за пределами текущего выделения вектора то это его проблемы, потому что нарушение предусловий вызова функции это и есть UB.
Не надо с больной головы переводить на буст ))Ты вообще ничего не понял... :(
Посмотри хоть в пример "на пальцах" 21455700 Надеюсь, поможет.
...
Рейтинг: 0 / 0
virtual methods
    #39652923
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devИ в чем же ложь? В том, что моё определение не соответствует дословно определению стандарта?Да. Это раздел про C++. Доморощенным определениям тут вряд ли место. А то так каждый будет выдумывать всё, что ему лично в данный момент удобно.Это то, что отличает "зубрилок" от вникающих в суть. Зубрилки, порой, дословно цитируют текст, но не могут понять суть того, что они цитируют, а вникающие в суть напротив - не помнят точно текст, но могут своими словами воспроизвести его смысл.
...
Рейтинг: 0 / 0
virtual methods
    #39652924
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devrdb_devпропущено...
И в чем же ложь? В том, что моё определение не соответствует дословно определению стандарта?
Где располагаются объекты, битовые поля или код функций?Давай-ка я перевормулирую поточнееДавай просто возьмём формулировку из стандарта. Это будет самой точной формулировкой, по определению. И мучаться, выдумывать что-то не надо.
...
Рейтинг: 0 / 0
virtual methods
    #39652926
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Да. Это раздел про C++. Доморощенным определениям тут вряд ли место. А то так каждый будет выдумывать всё, что ему лично в данный момент удобно.Это то, что отличает "зубрилок" от вникающих в суть. Зубрилки, порой, дословно цитируют текст, но не могут понять суть того, что они цитируют, а вникающие в суть напротив - не помнят точно текст, но могут своими словами воспроизвести его смысл.Я так понял, ты обиделся и перешёл на личности.
...
Рейтинг: 0 / 0
virtual methods
    #39652930
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestТы вообще ничего не понял... :(
Посмотри хоть в пример "на пальцах" 21455700 Надеюсь, поможет.
Зачем мне куда-то смотреть, если было утверждение "пример UB в boost", а в том примере не было UB.
Т.е. приведено ложное утверждение. Все.
...
Рейтинг: 0 / 0
virtual methods
    #39652931
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskya guestТы вообще ничего не понял... :(
Посмотри хоть в пример "на пальцах" 21455700 Надеюсь, поможет.
Зачем мне куда-то смотреть, если было утверждение "пример UB в boost", а в том примере не было UB.
Т.е. приведено ложное утверждение. Все.Ладно, последняя попытка. Я почему-то верю в людей до последнего, хотя обычно оказывается зря.

Даже если в векторе, скажем, 5 элементов, доступ к третьему элементу с таким определением оператора[] как в бусте скорее всего приведёт к UB. (Надо всё же проверить определение m_holder, есть малая вероятность что там возвращают из .start() не голый указатель, а класс-обёртку через который отмывают UB).

UB в boost в том смысле, что даже, казалось бы, не нарушая требования к вызову функции мы получаем UB.

Хотя бы так ясно?
...
Рейтинг: 0 / 0
virtual methods
    #39652933
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devпропущено...
Давай-ка я перевормулирую поточнееДавай просто возьмём формулировку из стандарта. Это будет самой точной формулировкой, по определению. И мучаться, выдумывать что-то не надо.Давай ка ты сейчас не заглядывая в текст стандарта процитируешь его слово в слово?
...
Рейтинг: 0 / 0
virtual methods
    #39652934
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Barlonerdb_devпропущено...
Угу!
Осталось объяснить это тем, кто пишет boost, компиляторы машинных кодов, потроха операционных систем, драйверы и прочим оптимизаторам.Ну-ка покажите пример из boost/потрохов операционных систем, который с точки зрения стандарта С++ приводил бы к UB...Вот более очевидный пример:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
   //! <b>Returns</b>: A pointer such that [data(),data() + size()) is a valid range.
   //!   For a non-empty vector, data() == &front().
   //!
   //! <b>Throws</b>: Nothing.
   //!
   //! <b>Complexity</b>: Constant.
   T* data() BOOST_NOEXCEPT_OR_NOTHROW
   { return this->priv_raw_begin(); }

Хоть буст и говорит, что "[data(),data() + size()) is a valid range" с точки зрения стандарта это мало что значит.
Вот такое, например
Код: plaintext
1.
2.
T* d = vec.data();
f(T[m]); // при условии size() > 1 и 1 <= m < size()


UB.

Конечно, UB как бы в пользовательском коде, т.к. он делает недопустимые операции. Но смысл в том, что переписать boost так, чтобы в использующем его коде не было UB — невозможно в принципе . Поэтому можно сказать, что UB в бусте.
...
Рейтинг: 0 / 0
virtual methods
    #39652935
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestЯ так понял, ты обиделся и перешёл на личности.Неа! На что тут обижаться? На то, что ты тычешь мне в нос текст стандарта, который не способен заучить наизусть? Да брось! :) Людей, способных запомнить весь текст стандарта слово в слово во всём мире по пальцам сосчитать.
Я не переходил на личности, а продемонстрировал разный подход к прохождению обучения в принципе, а не конкретно по отношению к кому-то.
...
Рейтинг: 0 / 0
virtual methods
    #39652937
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestДаже если в векторе, скажем, 5 элементов, доступ к третьему элементу с таким определением оператора[] как в бусте скорее всего приведёт к UB.
Еще раз. Не будет UB.
Даже если, как вы привели в том втором примере, каждый элемент вектора создавался отдельно через placement new, и "Никакого массива из int-ов в буфере нет. " .
Потому что согласно стандарту expr[i] эквивалентно *(expr + i), и никакой массив тут и не требуется. Достаточно чтобы там, по вычисленному адресу, который разыменовывается, был валидный объект, и он там есть.
А вот это ваше " т.к. индексация == адресная арифметика, а она определена только в пределах массива. " - вообще ни на чем не основано. Нет такого ограничения.
...
Рейтинг: 0 / 0
virtual methods
    #39652938
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestBasil 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-ов в буфере нет.
Нет здесь никакого UB ни при buffer[2], ни при buffer[3], ни даже при buffer[15], так как массив типа unsigned char создан на 16 элементов и каждый следующий buffer[n+1] это следующий unsigned char, а не int. Конечно, ты можешь инициализировать этот массив как тебе заблагорассудится!
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
  unsigned char buffer[sizeof(int)<<2];
  
  int* p = (int*)buffer;
  *(p++) = 0x33323130; *(p++) = 0x37363534; *(p++) = 0x3b3a3938;
  unsigned char* c = buffer;
  for (int i = 0; i < sizeof(buffer); i++)
  {
    printf("buffer[%i] = '%c'; *c = '%c'\r\n", i, (char)buffer[i], *(c++));
  }
...
Рейтинг: 0 / 0
virtual methods
    #39652940
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devНу так одним из частных случаев prvalue и есть нереферальный результат lvalue-to-rvalueМы обсуждали value category оператора *.Мы обсуждали взятие адреса - &
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)

Так что в прикладном коде такие трюки нельзя, если конечно не прибивать гвоздями к конкретному релизу конкретного компилятора, потому что такое может сломаться при любом обновлении.
...
Рейтинг: 0 / 0
virtual methods
    #39652941
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyПотому что согласно стандарту expr[i] эквивалентно *(expr + i), и никакой массив тут и не требуется.См. цитату из стандарта ниже.
http://eel.is/c draft/expr.add#4 When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand.
If the expression P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j] if 0≤i+j≤n; otherwise, the behavior is undefined. Likewise, the expression P - J points to the (possibly-hypothetical) element x[i−j] if 0≤i−j≤n; otherwise, the behavior is undefined.
Anatoly MoskovskyДостаточно чтобы там, по вычисленному адресу, который разыменовывается, был валидный объект, и он там есть.А вот это ваше "достаточно, чтобы там, по вычисленному адресу, который разыменовывается, был валидный объект" — вообще ни на чём не основано. Нет такого разрешения.
Anatoly MoskovskyА вот это ваше " т.к. индексация == адресная арифметика, а она определена только в пределах массива. " - вообще ни на чем не основано. Нет такого ограничения.См. цитату из стандарта выше.
...
Рейтинг: 0 / 0
virtual methods
    #39652942
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestAnatoly MoskovskyПотому что согласно стандарту expr[i] эквивалентно *(expr + i), и никакой массив тут и не требуется.См. цитату из стандарта ниже.
http://eel.is/c draft/expr.add#4When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand.
If the expression P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j] if 0≤i+j≤n; otherwise, the behavior is undefined. Likewise, the expression P - J points to the (possibly-hypothetical) element x[i−j] if 0≤i−j≤n; otherwise, the behavior is undefined.И? :)
Откомпилируй это: 21455918 и наслаждайся!
...
Рейтинг: 0 / 0
virtual methods
    #39652943
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Мы обсуждали value category оператора *.Мы обсуждали взятие адреса - & Я объяснил, из каких соображений в комитете считают применение оператора * к нулевому указателю UB.
И ты полез рассказывать, что это применение не приводит к чтению объекта. И предлагать свои определения для lvalue.

1. Ты правда считаешь, что никто (в комитете и вне его) не знает, что применение оператора * не приводит к доступу к объекту и нужно всех упорно просвещать?
2. Если хочешь сделать код не UB переопределяя lvalue, лучше сделать это в виде предложения в стандарт, а не обижаться тут на форуме.
...
Рейтинг: 0 / 0
virtual methods
    #39652944
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://eel.is/c draft/expr.add#4If the expression P points to element x[i] of an array object x with n elements ...
Этот пункт стандарта относится к массивам. А вы сами сказали, что "Никакого массива из int-ов в буфере нет. "
Зачем на него ссылаетесь?
...
Рейтинг: 0 / 0
virtual methods
    #39652945
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devОткомпилируй это: 21455918 и наслаждайся!Пардон, не та ссылка.
Вот правильная: 21455915
...
Рейтинг: 0 / 0
virtual methods
    #39652946
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovsky http://eel.is/c draft/expr.add#4If the expression P points to element x[i] of an array object x with n elements ...
Этот пункт стандарта относится к массивам. А вы сами сказали, что "Никакого массива из int-ов в буфере нет. "
Зачем на него ссылаетесь? Затем, что дальше написано, что otherwise behavior is undefined.
Массива нет — значит при адресной арифметике получается UB.

Вроде вопрос был откуда я взял что там UB и откуда требование про массив. Я ответил. Или опять не ясно?
...
Рейтинг: 0 / 0
virtual methods
    #39652947
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovsky http://eel.is/c draft/expr.add#4If the expression P points to element x[i] of an array object x with n elements ...
Этот пункт стандарта относится к массивам.Этот пункт стандарта относится к арифметике указателей. А других-то пунктов и нет =)
...
Рейтинг: 0 / 0
virtual methods
    #39652948
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devМы обсуждали взятие адреса - & Я объяснил, из каких соображений в комитете считают применение оператора * к нулевому указателю UB.
И ты полез рассказывать, что это применение не приводит к чтению объекта. И предлагать свои определения для lvalue.Что за бред?! Дашь ссылку на комментарий, где я изрёк подобную бредятину?
Смотри сюда: 21455820
rdb_deva guestКакой объект обозначает это lvalue, если оно применено к нулевому указателю?Какой тип указателя используешь, такой объект там и будет подразумеваться компилятором.
Что у нас там в далёком прошлом под DOS'ом располагалось в самом начале адресного пространства процессора Intel 8086? Таблица векторов прерываний (функций BIOS и DOS вызываемых машинной командой int)?
А что располагается сейчас в адресном пространстве пользовательского процесса Windows? 64кБ read-only памяти, каждый байт, которой, проинициализирован значением 0x00?Достаточно аргументированно?
...
Рейтинг: 0 / 0
virtual methods
    #39652949
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Я объяснил, из каких соображений в комитете считают применение оператора * к нулевому указателю UB.
И ты полез рассказывать, что это применение не приводит к чтению объекта. И предлагать свои определения для lvalue.Что за бред?! Дашь ссылку на комментарий, где я изрёк подобную бредятину? 21455748
Или в " И никакого доступа, приводящего к UB " под "доступом" не имелась в виду попытка чтения из объекта?
...
Рейтинг: 0 / 0
virtual methods
    #39652950
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestЭтот пункт стандарта относится к массивам.Этот пункт стандарта относится к арифметике указателей. А других-то пунктов и нет =)[/quot]Просто загляни в "legacy" - в стандарт ANSI C и внимательно изучи что такое массив и как работает арифметика типизированных указателей.
...
Рейтинг: 0 / 0
virtual methods
    #39652951
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestЭтот пункт стандарта относится к массивам.Этот пункт стандарта относится к арифметике указателей. А других-то пунктов и нет =)Просто загляни в "legacy" - в стандарт ANSI C и внимательно изучи что такое массив и как работает арифметика типизированных указателей.[/quot]
А при чём тут стандарт C, если обсуждается стандарт C++? Впрочем, в стандарте C то же самое написано: арифметика указателей разрешена внутри массива
When an expression that has integer type is added to or subtracted from a pointer, the
result has the type of the pointer operand. If the pointer operand points to an element of
an array object
, and the array is large enough, the result points to an element offset from
the original element such that the difference of the subscripts of the resulting and original
array elements equals the integer expression. In other words, if the expression P points to
the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and
(P)-N (where N has the value n) point to, respectively, the i+n-th and i−n-th elements of
the array object, provided they exist. Moreover, if the expression P points to the last
element of an array object, the expression (P)+1 points one past the last element of the
array object, and if the expression Q points one past the last element of an array object,
the expression (Q)-1 points to the last element of the array object. If both the pointer
operand and the result point to elements of the same array object, or one past the last
element of the array object, the evaluation shall not produce an overflow; otherwise, the
behavior is undefined
. If the result points one past the last element of the array object, it
shall not be used as the operand of a unary * operator that is evaluated.
Что теперь скажешь?
...
Рейтинг: 0 / 0
virtual methods
    #39652952
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestИли в " И никакого доступа, приводящего к UB " под "доступом" не имелась в виду попытка чтения из объекта?Какой может быть UB при выполнении команд процессора из откомпилированного бинарного файла? Там уже исключения... :)
...
Рейтинг: 0 / 0
virtual methods
    #39652953
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestА при чём тут стандарт C, если обсуждается стандарт C++?А при том, что ANSI C, это LEGACY С++ (читай как "наследство с обременением").

a guestВпрочем, в стандарте C то же самое написано: арифметика указателей разрешена внутри массиваМассивом может быть что угодно. Любой объект можно представить как массив байт, таблицу виртуальных методов можно представить как массив векторов и т.д. и т.п. Для этого даже не обязательно описывать как массив то, что ты хочешь представить как массив.
...
Рейтинг: 0 / 0
virtual methods
    #39652954
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestВпрочем, в стандарте C то же самое написано: арифметика указателей разрешена внутри массиваМассивом может быть что угодно. Любой объект можно представить как массивЯ уже понял, что у тебя что угодно может быть чем угодно.
Только мы тут C++ обсуждаем.
...
Рейтинг: 0 / 0
virtual methods
    #39652955
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestМассивом может быть что угодно. Любой объект можно представить как массивЯ уже понял, что у тебя что угодно может быть чем угодно.
Только мы тут C++ обсуждаем.[/quot]Это не у меня, это всегда так было и в C++, и в Си. Именно поэтому на Си до сих пор пишут внутренности операционных систем, прошивки контроллеров и прочую низкоуровневую фигню. :) Ты, случайно, не преподаватель в школе или ВУЗе?
...
Рейтинг: 0 / 0
virtual methods
    #39652957
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
a guestrdb_deva guestМассивом может быть что угодно. Любой объект можно представить как массивЯ уже понял, что у тебя что угодно может быть чем угодно.
Только мы тут C++ обсуждаем.Это не у меня, это всегда так было и в C++, и в Си. Именно поэтому на Си до сих пор пишут внутренности операционных систем, прошивки контроллеров и прочую низкоуровневую фигню. :) Ты, случайно, не преподаватель в школе или ВУЗе?После того, как тебе предъявили цитату из стандарта C, в который ты просил посмотреть, ты начал нести какую-то чушь.
Я думаю в таком виде продолжать беседу не имеет смысла. От тебя конкретики 0, только переходы на личности и виляния в сторону.
...
Рейтинг: 0 / 0
virtual methods
    #39652958
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestПосле того, как тебе предъявили цитату из стандарта C, в который ты просил посмотреть, ты начал нести какую-то чушь.
Я думаю в таком виде продолжать беседу не имеет смысла. От тебя конкретики 0, только переходы на личности и виляния в сторону.Для начала, прочти, что представляет из себя массив, почему к нему можно обращаться как к указателю, как осуществляется арифметика типизированных указателей и проверь всё это в отладчике. Потом придёшь и будешь спорить. Ok? :)
...
Рейтинг: 0 / 0
virtual methods
    #39652963
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestЗатем, что дальше написано, что otherwise behavior is undefined.
Массива нет — значит при адресной арифметике получается UB.

Вроде вопрос был откуда я взял что там UB и откуда требование про массив. Я ответил. Или опять не ясно?Любой типизированный указатель, формально, уже массив. Такая уж особенность у Си и C++... Другое дело, что в реальности никакого массива там может не быть из-за ошибки программиста, но компилятору об этом, порой, ничего не известно. Попробуй найти потенциальную ошибку в этом простом примере:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
#pragma pack(push, __ALIGN_DWORD)
struct A
{
  int Lo;
  int Hi;

  void* operator new(size_t sz, void* p) {return p;}
};
#pragma pack(pop)

A *a = (A*)malloc(sizeof(A)<<1);
new(&a[0]) A;
new(&a[1]) A;
a[0].Lo = 0x30; a[0].Hi = 0x31;
a[1].Lo = 0x32; a[1].Hi = 0x33;
...
Рейтинг: 0 / 0
virtual methods
    #39652984
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestBasil A. SidorovЯ повторю, что? насколько мне известно, placement new вообще ничего не делает с переданным ему буфером.А зачем он нужен, если ничего не делает? Можно не вызвать его тогда...
Так это, placement new конструкторы вызывает.
...
Рейтинг: 0 / 0
virtual methods
    #39653033
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Barlonea guestпропущено...
А зачем он нужен, если ничего не делает? Можно не вызвать его тогда...
Так это, placement new конструкторы вызывает.Спасибо, я в курсе.
Не я утверждал, что placement new ничего не делает.
...
Рейтинг: 0 / 0
virtual methods
    #39653038
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestBasil 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
    #39653047
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SiemarglБред.Аргументированно.
...
Рейтинг: 0 / 0
virtual methods
    #39653060
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestSiemarglБред.Аргументированно.Для тех, кто пользуется компилятором, вполне аргументировано. Религия не позволяет скомпилировать и пройтись отладчиком?
...
Рейтинг: 0 / 0
virtual methods
    #39653079
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestSiemarglБред.Аргументированно.Если почитать тот стандарт, что сам и приводил, и подумать, то (int*)buffer определен для [0..3].

для очистки совести можно завести еще переменную
Код: plaintext
1.
2.
3.
4.
5.
    char buffer[4*sizeof(int)];
    
    int *buffer2 = (int*)buffer;
    
    buffer2[2] = 3;
...
Рейтинг: 0 / 0
virtual methods
    #39653084
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SiemarglЕсли почитать тот стандарт, что сам и приводил, и подумать, то (int*)buffer определен для [0..3].

для очистки совести можно завести еще переменную
Код: plaintext
1.
2.
3.
4.
5.
    char buffer[4*sizeof(int)];
    
    int *buffer2 = (int*)buffer;
    
    buffer2[2] = 3;

Я ему об этом уже писал 21455915 , но он не читает и ничего компилировать и проверять не хочет. Просто троллит.
...
Рейтинг: 0 / 0
virtual methods
    #39653087
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Siemargla guestпропущено...
Аргументированно.Если почитать тот стандарт, что сам и приводил, и подумать, то (int*)buffer определен для [0..3].А если перечитать ещё раз (внимательно) и ещё подумать (подольше), то прибавление [0..3] к указателю (int*)buffer не определено, т.к. указатель (int*)buffer не является указателем на элемент массива нужного размера, т.к никакого массива из int там вообще нет.
...
Рейтинг: 0 / 0
virtual methods
    #39653117
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestА если перечитать ещё раз (внимательно) и ещё подумать (подольше), то прибавление [0..3] к указателю (int*)buffer не определено, т.к. указатель (int*)buffer не является указателем на элемент массива нужного размера, т.к никакого массива из int там вообще нет.Еще раз (сбился со счёта - в какой) - твой массив состоит из 16-ти элементов unsigned char ( unsigned char buffer[4 * sizeof(int)] ) и в нём прекрасно умещается 4 элемента любого типа размером 4 байта (UINT32, INT32 или int в моделях ILP32, I32LP64, LLP64, LP64), поэтому, для доступа к этим 4-ём элементам int ничто не мешает использовать приведенный к int* указатель на массив buffer, а также использовать арифметику указателей с обычный указателем на unsigned char:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
  UINT8 buffer[sizeof(INT32)<<2];
  
  PINT32 p = (PINT32)buffer;
  *(p++) = 0x33323130; *(p++) = 0x37363534; *(p++) = 0x3b3a3938;
  PINT8 c = buffer;
  for (int i = 0; i < sizeof(buffer); i++)
  {
    printf("buffer[%i] = '%c'; *c = '%c'\r\n", i, buffer[i], *(c++));
  }
...
Рейтинг: 0 / 0
virtual methods
    #39653123
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestЗатем, что дальше написано, что otherwise behavior is undefined.
Вы читать-то научитесь.
Вот вся фраза.
"If the expression P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j] if 0≤i+j≤n; otherwise, the behavior is undefined"
В ней утверждается,что
1) Если x массив длиной N
2) Есть выражение P равное &x[i]
3) То выражение P + j равно &x[i + j] если 0<=i+j<=n
4) А если не выполняется 0<=i+j<=n, то выражение P + j дает UB (а вовсе не "если это не массив, то UB", как вы в порядке бреда поняли ).
...
Рейтинг: 0 / 0
virtual methods
    #39653135
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskya guestЗатем, что дальше написано, что otherwise behavior is undefined.
Вы читать-то научитесь.
Вот вся фраза.
"If the expression P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j] if 0≤i+j≤n; otherwise, the behavior is undefined"
В ней утверждается,что
1) Если x массив длиной N
2) Есть выражение P равное &x[i]
3) То выражение P + j равно &x[i + j] если 0<=i+j<=n
4) А если не выполняется 0<=i+j<=n, то выражение P + j дает UB (а вовсе не "если это не массив, то UB", как вы в порядке бреда поняли )."otherwise" относится к "If". Какое-то из условий в if не выполнено — UB.

Короче, если ты хочешь показать, что я принёс не ту цитату из стандарта, притащи определение арифметики указателей для случая, когда указатель не указывает на элемент массива. И пруф вот этой Anatoly Moskovskyи никакой массив тут и не требуется. Достаточно чтобы там, по вычисленному адресу, который разыменовывается, был валидный объект чуши.
...
Рейтинг: 0 / 0
virtual methods
    #39653138
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Siemargla guestпропущено...
А если перечитать ещё раз (внимательно) и ещё подумать (подольше), то прибавление [0..3] к указателю (int*)buffer не определено, т.к. указатель (int*)buffer не является указателем на элемент массива нужного размера, т.к никакого массива из int там вообще нет.С тобой нет смысла разговаривать.Естественно. У тебя из "аргументов" только "Бред". Ни одной ссылки на стандарт. Пукнул в лужу, а когда тебе отказались верить без обоснований — слился.
...
Рейтинг: 0 / 0
virtual methods
    #39653140
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestAnatoly Moskovsky"If ... if 0≤i+j≤n; otherwise, the behavior is undefined""otherwise" относится к "If".К какому из двух, говорите???
...
Рейтинг: 0 / 0
virtual methods
    #39653145
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Basil A. Sidorova guestпропущено...
"otherwise" относится к "If".К какому из двух, говорите???Точку с запятой перед otherwise видишь? Что она значит? Почему там не запятая?
...
Рейтинг: 0 / 0
virtual methods
    #39653149
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest"otherwise" относится к "If". Какое-то из условий в if не выполнено — UB.
Нет. Учите язык.

Во фразе
"If A, B if C; otherwise, D" otherwise относится к if C, потому что во-первых оно ближе, во вторых первый if отделен запятой, то есть это предусловия для всей оставшейся фразы.
...
Рейтинг: 0 / 0
virtual methods
    #39653159
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestТочку с запятой перед otherwise видишь? Что она значит? Почему там не запятая?"Ты идешь по очень тонкому льду, мой друг педигрипал" (ц) Кирпич.вводнаяIf the expression P points to element x[i] of an array object x with n elements, логический разделительthe expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j]определение эквивалентностиif 0≤i+j≤nусловие, нарушение которого даёт неопределённое поведение.

P.S.
А точку с запятой, обычно, ставят там, где не хотят начинать новое предложение.
"А Владимир Ильич всё бреется; а мог бы и полоснуть".
...
Рейтинг: 0 / 0
virtual methods
    #39653163
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чтобы было еще понятнее

"If A, B if C; otherwise, D" надо читать так:

"If A and C then B else if not (A and C) then D"
...
Рейтинг: 0 / 0
virtual methods
    #39653165
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Упс, запутался раскрывая скобки

Вот так:
"If A and C then B else if A and not C then D"
...
Рейтинг: 0 / 0
virtual methods
    #39653173
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskya guest"otherwise" относится к "If". Какое-то из условий в if не выполнено — UB.
Нет. Учите язык.И вам того же.

Anatoly MoskovskyВо фразе
"If A, B if C; otherwise, D" otherwise относится к if CНет.
Anatoly Moskovskyоно ближеВот поэтому приходится использовать точку с запятой, чтобы показать, что otherwise относится ко всему первому простому предложению сложного предложения, а не к ближайшему if.
Точка с запятой разделяет (и связывает) более "масштабные" части предложения, чем запятая. Запятая внутри простого предложения, точка с запятой — для разделения (связывания) простых предложений сложного предложения.
...
Рейтинг: 0 / 0
virtual methods
    #39653176
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Basil A. SidorovА точку с запятой, обычно, ставят там, где не хотят начинать новое предложение.Золотые слова. Подтверждает вышенаписанное мной про разделение простых предложений сложного предложения. Можно превратить сложное предложение в 2 простых, разделив вместо точки запятой точкой.
...
Рейтинг: 0 / 0
virtual methods
    #39653177
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyЧтобы было еще понятнеепринеси уже определение арифметики указателей для случая, когда указатель не указывает на элемент массива.
...
Рейтинг: 0 / 0
virtual methods
    #39653201
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где найти стандарт, не знаю. Попытался читать результаты гугля по "pointer arithmetic" и складывается ощущение, что a guest прав

Наиболее "читаемый" текст по ссылке http://en.cppreference.com/w/cpp/language/operator_arithmetic

MSDN так же, про pointer arithmetic говорит исключительно о массивах. Даже в книжке Programming in C: A Tutorial
Brian W. Kernighan примеры (одна страничка) исключительно о перемещениях по массиву.

IMHO

note: стандарта не знаю, не читал. Но в google, что либо противоречащие мнению a.guest найти не смог. Где взять стандарт, не знаю.


If any of the operands is a pointer, the following rules apply:

* A pointer to non-array object is treated as a pointer to the first element of an array with size 1.
* If the pointer P points to the ith element of an array, then the expressions P+n, n+P, and P-n are pointers of the same type that point to the i+nth, i+nth, and i-nth element of the same array, respectively. The result of pointer addition may also be a one-past-the-end pointer (that is, pointer P such that the expression P-1 points to the last element of the array). Any other situations (that is, attempts to generate a pointer that isn't pointing at an element of the same array or one past the end) invoke undefined behavior.
* If the pointer P points to the ith element of an array, and the pointer Q points at the jth element of the same array, the expression P-Q has the value i-j, if the value fits in std::ptrdiff_t. Both operands must point to the elements of the same array (or one past the end), otherwise the behavior is undefined. If the result does not fit in std::ptrdiff_t, the behavior is undefined.
* In any case, if the pointed-to type is different from the array element type, disregarding cv qualifications, at every level if the elements are themselves pointers, the behavior of pointer arithmetic is undefined. In particular, pointer arithmetic with pointer to base, which is pointing at an element of an array of derived objects is undefined.
* If the value ​0​ is added or subtracted from a pointer, the result is the pointer, unchanged. If two pointers point at the same object or are both one past the end of the same array, or both are null pointers, then the result of subtraction is equal to (std::ptrdiff_t)0.

...
Рейтинг: 0 / 0
virtual methods
    #39653202
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Leonid KudryavtsevГде найти стандарт, не знаю.Можно просто драфты смотреть, не обязательно покупать стандарт.
Текущая версия с удобной навигацией http://eel.is/c draft/
Сборник драфтов в .pdf-формате https://github.com/cplusplus/draft/tree/master/papers
...
Рейтинг: 0 / 0
virtual methods
    #39653222
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestBasil 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-ов в буфере нет.На самом деле, UB тут есть, но совсем в другом месте. unsigned char buffer[4*sizeof(int)] не гарантирует нужного для int выравнивания, и даже обращение к ((int *)buffer)[0] может привести к проблемам.
...
Рейтинг: 0 / 0
virtual methods
    #39653223
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BarloneНа самом деле, UB тут есть, но совсем в другом месте. unsigned char buffer[4*sizeof(int)] не гарантирует нужного для int выравнивания, и даже обращение к ((int *)buffer)[0] может привести к проблемам.Считай, там есть alignas(int) и с созданием объектов с помощью placement new всё в порядке. ((int *)buffer)[0] тоже в порядке.
...
Рейтинг: 0 / 0
virtual methods
    #39653225
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestЕсли почитать тот стандарт, что сам и приводил, и подумать, то (int*)buffer определен для [0..3].А если перечитать ещё раз (внимательно) и ещё подумать (подольше), то прибавление [0..3] к указателю (int*)buffer не определено, т.к. указатель (int*)buffer не является указателем на элемент массива нужного размера, т.к никакого массива из int там вообще нет.[/quot]Но вот это точно бред. С памятью, выделенной malloc, работать как с массивом вообще никак нельзя, да?
...
Рейтинг: 0 / 0
virtual methods
    #39653226
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
упс, что-то с цитированием...
...
Рейтинг: 0 / 0
virtual methods
    #39653227
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
a guest((int *)buffer)[0] тоже в порядке.Ну или не в порядке, но std::launder я показывать не хочу, у народа с пониманием более простых вещей тут явные проблемы.
...
Рейтинг: 0 / 0
virtual methods
    #39653230
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestпринеси уже определение арифметики указателей для случая, когда указатель не указывает на элемент массива.
Сначала докажите что там не массив
...
Рейтинг: 0 / 0
virtual methods
    #39653231
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну так посмотрите: 7.2 Array-to-pointer conversion .
...
Рейтинг: 0 / 0
virtual methods
    #39653232
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BarloneНо вот это точно бред. С памятью, выделенной malloc, работать как с массивом вообще никак нельзя, да?

По драфту... если переводить дословно... нет ))), нельзя )))

http://eel.is/c draft/expr.add
For addition or subtraction, if the expressions P or Q have type “pointer to cv T”, where T and the array element type are not similar, the behavior is undefined.
...
Рейтинг: 0 / 0
virtual methods
    #39653234
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestМожно просто драфты смотреть, не обязательно покупать стандарт.
Текущая версия с удобной навигацией http://eel.is/c draft/
Сборник драфтов в .pdf-формате https://github.com/cplusplus/draft/tree/master/papers Давай будем читать "твои" черновики вместе... :)
draftWhen an expression that has integer type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integer expression. In other words, if the expression P points to the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and (P)-N (where N has the value n) point to, respectively, the i+n-th and i−n-th elements of the array object, provided they exist. Moreover, if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object, and if the expression Q points one past the last element of an array object, the expression (Q)-1 points to the last element of the array object. If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined. If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated.
ПереводКогда выражение, имеющее целочисленный тип прибавлено или вычтено из указателя, результат имеет тип операнда указателя. Если операнд указателя указывает на объект элемента массива и массив достаточно велик, результат указывает на смещение элемента от начального элемента так, что разница индексов результирующего и начального элемента массива является целочисленным выражением. Иными словами, если выражение P указывает на i-тый объект элемента массива, выражение (P)+N (в арифметике указателей тоже, что N+(P)) и (P)-N (где N имеет значение n) указывают, соответственно, на i+n-ый и i-n-ый объект элементов массива, если они существуют. Более того, если выражение P указывает на объект последнего элемента массива, выражение (P)+1 указывает следующий объект элемента массива после последнего и если выражение Q указывает следующий после последнего объект элемента массива, выражение (Q)-1 указывает на последний объект элемента массива. Если оба, и операнд указателя, и результат указывают на один и тот же объект массива или на следующий за последним объект элемента массива, результатом оценки выражения не должно являться переполнение, в противном случае, поведение не определено. Если результат указыват на следующий за последним объект элемента массива, этот результат не должен быть использован в качестве операнда унарного оператора * (разыменование указателя).

Примечание: Здесь под элементом массива понимается некая абстрактная единица хранения массива, имеющая размер хранящегося в ней объекта, а под объектом элемента понимается экземпляр любого типа, хранящийся в элементе массива, а не только экземпляр какого-либо класса.

Иными словами, для твоего примера:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
UINT8 buffer[4 * sizeof(INT32)];

PUINT8 c = &buffer[15];           //-- Нет UB
PINT32 p = &((PINT32)buffer)[3];  //-- Нет UB
с += 1;  //-- нет UB !!! (тоже, что (&buffer[15])++ или &buffer[16])
p += 1;  //-- нет UB !!! (тоже, что (&((PINT32)buffer)[3])++ или &((PINT32)buffer)[4])
printf("%c, %i", *c, *p); //-- есть UB !!!
c += 1;  //-- есть UB !!!
p += 1;  //-- есть UB !!!


А теперь попробуй пояснить, как компилятор должен определить UB в подобном примере:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
UINT8 buffer[sizeof(int) << 2];
PUINT8 c = &buffer[8];
int direction;
for (int i = 0; i < 100; i++)
{
  direction = std::rand() - ((int)RAND_MAX >> 1);
  if (direction > 0)
    c++;
  else
    c--;
  printf("c = '%c'", *c);
}
...
Рейтинг: 0 / 0
virtual methods
    #39653235
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Barlonea guestBarloneЕсли почитать тот стандарт, что сам и приводил, и подумать, то (int*)buffer определен для [0..3].А если перечитать ещё раз (внимательно) и ещё подумать (подольше), то прибавление [0..3] к указателю (int*)buffer не определено, т.к. указатель (int*)buffer не является указателем на элемент массива нужного размера, т.к никакого массива из int там вообще нет.Но вот это точно бред.Аргументированно, как обычно на этом форуме.

BarloneС памятью, выделенной malloc, работать как с массивом вообще никак нельзя, да?Пока там не создан массив с помощью placement new — нельзя.
...
Рейтинг: 0 / 0
virtual methods
    #39653236
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, так вы правда утверждаете, что с памятью, выделенной malloc, нельзя работать как с массивом?
...
Рейтинг: 0 / 0
virtual methods
    #39653239
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskya guestпринеси уже определение арифметики указателей для случая, когда указатель не указывает на элемент массива.
Сначала докажите что там не массив Запросто: его там не создавали, значит его там нет.
Если вы не знаете таких базовых вещей (как создаются объекты в C++), зачем лезете?
...
Рейтинг: 0 / 0
virtual methods
    #39653240
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну в целом смысл закладываемый драфтом, понятен

1) за "ручное" cast'ование типов, draft ответственности не несет.
2) операции могут перегружаться. Т.ч. даже "выход за пределы массива" (кроме элемента сразу за последним), undefined. Т.к. если там какая-то коллекция, то она может такие факты и проверить.

IMHO

P.S. Перефразируя известное проклятие "что бы тебе всю жизнь программировать строго следуя спецификациям" )))
...
Рейтинг: 0 / 0
virtual methods
    #39653241
Siemargl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barlonea guestBasil 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-ов в буфере нет.На самом деле, UB тут есть, но совсем в другом месте. unsigned char buffer[4*sizeof(int)] не гарантирует нужного для int выравнивания, и даже обращение к ((int *)buffer)[0] может привести к проблемам.
Такое бывает на некоторых архитектурах (int только по четным адресам), но тогда placement new бы ругнулся
...
Рейтинг: 0 / 0
virtual methods
    #39653242
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestЗапросто: его там не создавали, значит его там нет.
Код: plaintext
1.
2.
3.
{
   int a[2];
}


Вот тут массив создан или нет?
...
Рейтинг: 0 / 0
virtual methods
    #39653243
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Leonid Kudryavtsev1) за "ручное" cast'ование типов, draft ответственности не несет.То есть? Поведение многих кастов вполне описано и определено.
...
Рейтинг: 0 / 0
virtual methods
    #39653246
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskya guestЗапросто: его там не создавали, значит его там нет.
Код: plaintext
1.
2.
3.
{
   int a[2];
}


Вот тут массив создан или нет?Детсадовская попытка подловить, дописав что-нибудь над и под фигурными скобками, которые сделают любой мой ответ неверным?
...
Рейтинг: 0 / 0
virtual methods
    #39653247
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestBarloneпропущено...
Но вот это точно бред.Аргументированно, как обычно на этом форуме. 21457288
Какие тебе еще нужны аргументы? :)

a guestBarloneС памятью, выделенной malloc, работать как с массивом вообще никак нельзя, да?Пока там не создан массив с помощью placement new — нельзя. Неужели? Забавно, но в Си нет ни new, ни placement new, однако, библиотечным функциям работы со строками (strlen, strcpy и т.д.), а также библиотечным функциям работы с памятью (memcpy, memset, memmove и т.д.) сей факт абсолютно никак не мешает, при том, что Си, как я уже упоминал, является для C++ наследием.
...
Рейтинг: 0 / 0
virtual methods
    #39653249
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestAnatoly Moskovskyпропущено...
Сначала докажите что там не массив Запросто: его там не создавали, значит его там нет.
Если вы не знаете таких базовых вещей (как создаются объекты в C++), зачем лезете?
В мемориз! Скриньте это, парни!!!
...
Рейтинг: 0 / 0
virtual methods
    #39653250
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestКак, если ты даже не умеешь читать? Покажи, с какого драфта ты скопировал то, что у тебя написано под спойлером.С какого драфта ты это цитировал, с того и взято. Я просто взял твою цитату драфта.
...
Рейтинг: 0 / 0
virtual methods
    #39653252
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestПока там не создан массив с помощью placement new — нельзя. Неужели? Забавно, но в Си нет ни new, ни placement new, однако, библиотечным функциям работы со строками (strlen, strcpy и т.д.), а также библиотечным функциям работы с памятью (memcpy, memset, memmove и т.д.) сей факт абсолютно никак не мешаетВ C и C++ разная семантика создания объектов. Аналогии с C тут не к месту.
rdb_devСи, как я уже упоминал, является для C++ наследием.Отсюда не следует ничего.
...
Рейтинг: 0 / 0
virtual methods
    #39653258
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestДетсадовская попытка подловить, дописав что-нибудь над и под фигурными скобками, которые сделают любой мой ответ неверным?
Код: plaintext
1.
2.
3.
4.
{
   int a[2];
   // Вот тут массив создан или нет?
}


Ответ-то есть?
...
Рейтинг: 0 / 0
virtual methods
    #39653260
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskya guestДетсадовская попытка подловить, дописав что-нибудь над и под фигурными скобками, которые сделают любой мой ответ неверным?
Код: plaintext
1.
2.
3.
4.
{
   int a[2];
   // Вот тут массив создан или нет?
}


Ответ-то есть?Открой стандарт (или драфт). Там написано, как создаются объекты.
...
Рейтинг: 0 / 0
virtual methods
    #39653261
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devпропущено...
Неужели? Забавно, но в Си нет ни new, ни placement new, однако, библиотечным функциям работы со строками (strlen, strcpy и т.д.), а также библиотечным функциям работы с памятью (memcpy, memset, memmove и т.д.) сей факт абсолютно никак не мешаетВ C и C++ разная семантика создания объектов. Аналогии с C тут не к месту.В Си нет классов, а массивы есть! :)

a guestrdb_devСи, как я уже упоминал, является для C++ наследием.Отсюда не следует ничего.Как же не к месту, если C++ полностью наследует Си, включая создание массивов, приведение указателей и арифметику указателей? O_o
...
Рейтинг: 0 / 0
virtual methods
    #39653266
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestLeonid Kudryavtsev1) за "ручное" cast'ование типов, draft ответственности не несет.То есть? Поведение многих кастов вполне описано и определено.

Я про желание скастовать массив char[] в массив int[]

rdb_deva guestпропущено...
Запросто: его там не создавали, значит его там нет.
Если вы не знаете таких базовых вещей (как создаются объекты в C++), зачем лезете?
В мемориз! Скриньте это, парни!!!

Вот честно говоря, ничего смешного не увидел

A.Quest совершенно прав
Там массив char (и при этом даже "не сырая" память от какого нибудь malloc'а, а "честный" массив char)
А массив int, это массив другого типа.

То, что это относительно однозначно будет работать на Intel архитектуре - всем понятно. Но стандарты на язык пишутся для разных архитектур. Об одном подводном камне (выравнивание) уже вспомнили.
...
Рейтинг: 0 / 0
virtual methods
    #39653271
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devC++ полностью наследует СиЭто не так.
...
Рейтинг: 0 / 0
virtual methods
    #39653274
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Leonid KudryavtsevОб одном подводном камне (выравнивание) уже вспомнили.Я просто забыл написать alignas. Цель примера была показать не проблемы с выравниванием, об этом и так многие знают. Считайте, что с выравниванием всё ок.
...
Рейтинг: 0 / 0
virtual methods
    #39653276
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestОткрой стандарт (или драфт). Там написано, как создаются объекты.
Понятно, т.е. ответа нет.

Из этого можно сделать вывод что мальчик путает созданный массив и проинициализированный массив, и не считает первое массивом
...
Рейтинг: 0 / 0
virtual methods
    #39653277
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevТо, что это относительно однозначно будет работать на Intel архитектуре - всем понятно. Но стандарты на язык пишутся для разных архитектур. Об одном подводном камне (выравнивание) уже вспомнили.То есть, предлагаешь проверить всё это в g++ подобном компиляторе на платформе "Эльбрус", где существует некоторая типизация хранимых в памяти данных на уровне процессора? Не поверишь, но обычный Линух, собранный их же g++ подобным компилятором, работает на этой платформе, а в потрохах Линуха чего только нет... ;)
...
Рейтинг: 0 / 0
virtual methods
    #39653281
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskya guestОткрой стандарт (или драфт). Там написано, как создаются объекты.
Понятно, т.е. ответа нет.Ты настолько беспомощен, что не можешь найти http://eel.is/c draft/intro.object#def:object ?
Я даже процитирую сюда
http://eel.is/c draft/intro.object#def:object An object is created by a definition ([basic.def]), by a new-expression, when implicitly changing the active member of a union ([class.union]), or when a temporary object is created ([conv.rval], [class.temporary]).
Если int a[2]; у тебя это definition, то да, там массив создаётся.

Anatoly MoskovskyИз этого можно сделать вывод что мальчик путает созданный массив и проинициализированный массив, и не считает первое массивом Мимо, как обычно.
...
Рейтинг: 0 / 0
virtual methods
    #39653291
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsevrdb_devпропущено...

В мемориз! Скриньте это, парни!!!Вот честно говоря, ничего смешного не увидел

A.Quest совершенно прав
Там массив char (и при этом даже "не сырая" память от какого нибудь malloc'а, а "честный" массив char)
А массив int, это массив другого типа.

То, что это относительно однозначно будет работать на Intel архитектуре - всем понятно. Но стандарты на язык пишутся для разных архитектур. Об одном подводном камне (выравнивание) уже вспомнили.Тогда объясни мне пожалуйста такой момент:
Допустим, я пишу на C++ какой-нибудь GRUB подобный загрузчик, работающий в реальном режиме адресации процессора семейства Intel x86 и мне надо перехватить прерывание divide by zero, перенаправив обработку этого исключения на свой обработчик этого прерывания, если:
a) Таблица векторов прерываний располагается по адресу 0000:0;
б) Я в своей программе не размещал и не инициализировал массив этой таблицы векторов прерываний по адресу 0000:0 (это сделал BIOS);
в) Вектор прерывания divide by zero является первым элементом этой таблицы, а взятие элемента по нулевому указателю, это UB;

Или, например, такой вариант:
MS DirectX использует прямой доступ к памяти видеоконтроллера, картированной на адресное пространство процессора. Как реализация DirectX должна работать с видеопамятью, если она не создавала этот "массив байт" видеопамяти, в котором находится массив структур RGB которые, при разных режимах работы видеоконтроллера, могут иметь разный размер - от 2 до 4-х байт? :)
...
Рейтинг: 0 / 0
virtual methods
    #39653298
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestЯ даже процитирую сюда
Правильно. Тот кто утверждает чушь и должен работать доказывая свои утверждения.
Остальным-то чего напрягаться.

Теперь доказывайте, что конструкция в которой в массиве uchar[] по очереди созданы элементы типа T, при том что все они помещаются внутрь того массива, не является массивом.
...
Рейтинг: 0 / 0
virtual methods
    #39653300
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyПравильно. Тот кто утверждает чушь и должен работать доказывая свои утверждения.Тогда почему ты утверждаешь чушь и не особо спешишь её обосновывать?

Anatoly MoskovskyТеперь доказывайте, что конструкция в которой в массиве uchar[] по очереди созданы элементы типа T, при том что все они помещаются внутрь того массива, не является массивом.Отсутствие не доказывают.
...
Рейтинг: 0 / 0
virtual methods
    #39653304
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestТогда почему ты утверждаешь чушь и не особо спешишь её обосновывать?
Ну, это же не я написал "вот код в котором UB".
Придется доказывать тому кто написал.
Пока не видно доказательства. Вместо этого видно, что утвержается что пол-языка это UB.
...
Рейтинг: 0 / 0
virtual methods
    #39653309
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskya guestТогда почему ты утверждаешь чушь и не особо спешишь её обосновывать?
Ну, это же не я написал "вот код в котором UB".И этоAnatoly Moskovskyи никакой массив тут и не требуется. Достаточно чтобы там, по вычисленному адресу, который разыменовывается, был валидный объектне ты писал?
...
Рейтинг: 0 / 0
virtual methods
    #39653312
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyНу, это же не я написал "вот код в котором UB".
Придется доказывать тому кто написал.
Пока не видно доказательства. Вместо этого видно, что утвержается что пол-языка это UB.Более того - хренова туча написанных на Си/C++ и работающих программ, по заверениям "гостя" работать не должна и не может!
...
Рейтинг: 0 / 0
virtual methods
    #39653318
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devAnatoly MoskovskyНу, это же не я написал "вот код в котором UB".
Придется доказывать тому кто написал.
Пока не видно доказательства. Вместо этого видно, что утвержается что пол-языка это UB.Более того - хренова туча написанных на Си/C++ и работающих программ, по заверениям "гостя" работать не должна и не может! Цитату сюда, где я утверждаю такое.
...
Рейтинг: 0 / 0
virtual methods
    #39653324
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, так что, ответ на это:
rdb_deva guestКак, если ты даже не умеешь читать? Покажи, с какого драфта ты скопировал то, что у тебя написано под спойлером.С какого драфта ты это цитировал, с того и взято. Я просто взял твою цитату драфта. будет? Или ты, таки, сам себя слил?
...
Рейтинг: 0 / 0
virtual methods
    #39653328
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guest, так что, ответ на это:
rdb_devпропущено...
С какого драфта ты это цитировал, с того и взято. Я просто взял твою цитату драфта. будет? Или ты, таки, сам себя слил?Смысл писать ответы, если ты не умеешь читать? Перечитай ещё раз, откуда бралась цитата и куда ты её приписал. Может, дойдёт после N-го перечитывания.
...
Рейтинг: 0 / 0
virtual methods
    #39653331
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devпропущено...
Более того - хренова туча написанных на Си/C++ и работающих программ, по заверениям "гостя" работать не должна и не может! Цитату сюда, где я утверждаю такое.Разве не ты здесь утверждаешь, что UB, это полный "ай-ай-ай" и что массив обязательно должен быть создан и инициализирован программой прежде, чем иметь к нему доступ. Может еще массив должен быть создан и инициализирован в той же самой единице компиляции, в одном потоке исполнения, чтобы программа могла "честно" получить к нему доступ? :) Бедные писатели драйверов и сервисов... "а мужики-то не знают!". Что уж говорить про тех, кто пользует mapped-memory файлы...
...
Рейтинг: 0 / 0
virtual methods
    #39653332
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestСмысл писать ответы, если ты не умеешь читать? Перечитай ещё раз, откуда бралась цитата и куда ты её приписал. Может, дойдёт после N-го перечитывания.Еще раз для тех, кто в бронепоезде - это ТВОЯ цитата драфта, а не моя. :) Я лишь сделал copy-past и написал перевод.
...
Рейтинг: 0 / 0
virtual methods
    #39653338
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestСмысл писать ответы, если ты не умеешь читать? Перечитай ещё раз, откуда бралась цитата и куда ты её приписал. Может, дойдёт после N-го перечитывания.Еще раз для тех, кто в бронепоезде - это ТВОЯ цитата драфта, а не моя. :) Я лишь сделал copy-past и написал перевод. Перечитай ещё раз. Явно не дошло.
...
Рейтинг: 0 / 0
virtual methods
    #39653340
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, так где в этом примере UB, дружище? Покажешь?
Компилятор не ругается и собирает из команд процессора вполне ожидаемый и рабочий код... :)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
UINT8 buffer[sizeof(int) << 2];
PUINT8 c = &buffer[8];
int direction;
for (int i = 0; i < 100; i++)
{
  direction = std::rand() - RAND_MAX;
  if (direction > 0)
    c++;
  else
    c--;
  printf("c = '%c'", *c);
}
...
Рейтинг: 0 / 0
virtual methods
    #39653345
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devКомпилятор не ругается и собирает из команд процессора вполне ожидаемый и рабочий код... :)1. И что из этого следует?
2. "ожидаемы" — ещё понятно. А что такое "рабочий"? Нет недопустимых инструкций?
...
Рейтинг: 0 / 0
virtual methods
    #39653348
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest1. И что из этого следует?
2. "ожидаемы" — ещё понятно. А что такое "рабочий"? Нет недопустимых инструкций?Где в этом коде UB? :)
...
Рейтинг: 0 / 0
virtual methods
    #39653354
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guest1. И что из этого следует?
2. "ожидаемы" — ещё понятно. А что такое "рабочий"? Нет недопустимых инструкций?Где в этом коде UB?UB возникает во время выполнения и зависит от значений переменных.
Хочешь продолжать обсуждение ­— пиши код без изъёбов. Я не собираюсь разбираться в ветках if-ов и смотреть, что там на какой итерации цикла будет.
...
Рейтинг: 0 / 0
virtual methods
    #39653358
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devпропущено...
Где в этом коде UB?UB возникает во время выполнения и зависит от значений переменных.И в чём же, во время выполнения, это UB выражается? :)
...
Рейтинг: 0 / 0
virtual methods
    #39653369
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
UB возникает во время выполнения и зависит от значений переменных.И в чём же, во время выполнения, это UB выражается? :)В чём угодно.
...
Рейтинг: 0 / 0
virtual methods
    #39653374
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devИ в чём же, во время выполнения, это UB выражается? :)В чём угодно.Например?
...
Рейтинг: 0 / 0
virtual methods
    #39653377
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_deva guestпропущено...
UB возникает во время выполнения и зависит от значений переменных.И в чём же, во время выполнения, это UB выражается? :)
Скомпилировал в QT. Запустил программу 2-а раза. Ищите отличия сами.
(почему она не свалилась на GPF я не очень понимаю)

В общем, вполне себе undefined бехевиар проявляется )))
...
Рейтинг: 0 / 0
virtual methods
    #39653378
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
virtual methods
    #39653380
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
virtual methods
    #39653381
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest
BarloneС памятью, выделенной malloc, работать как с массивом вообще никак нельзя, да?Пока там не создан массив с помощью placement new — нельзя.Интересная точка зрения. И главное, я не могу найти в стандарте ее опровержения. А есть какие-нибудь обсуждения, комментарии по этому поводу (кроме этой темы)?
...
Рейтинг: 0 / 0
virtual methods
    #39653385
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Barlonea guestпропущено...
Пока там не создан массив с помощью placement new — нельзя.Интересная точка зрения. И главное, я не могу найти в стандарте ее опровержения. А есть какие-нибудь обсуждения, комментарии по этому поводу (кроме этой темы)? https://groups.google.com/a/isocpp.org/d/msg/std-discussion/p4BXNhTHY7U/ahp5CzNFQQAJ
...
Рейтинг: 0 / 0
virtual methods
    #39653396
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Barlonea guestпропущено...
Пока там не создан массив с помощью placement new — нельзя.Интересная точка зрения. И главное, я не могу найти в стандарте ее опровержения. А есть какие-нибудь обсуждения, комментарии по этому поводу (кроме этой темы)? http://wg21.link/p0593r2
...
Рейтинг: 0 / 0
virtual methods
    #39653403
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevСкомпилировал в QT. Запустил программу 2-а раза. Ищите отличия сами.
(почему она не свалилась на GPF я не очень понимаю)
В общем, вполне себе undefined бехевиар проявляется )))Так а почему она должна была свалиться на GPF? Сколько потоку отводится на стек по умолчанию? 1МБ? :)
Если сильно повезёт, то указатель не выскочит за пределы массива, а если не повезёт, будет выводить на экран символы за пределами кадра стека текущей функции (может даже выводить байты адресов возврата, сохраненных копий указателя стека и много другого). Крайне маловероятно, что при 100 итерациях мы выскочим вверх за пределы начала стека, получив исключение general protection failure или page fault.
...
Рейтинг: 0 / 0
virtual methods
    #39653419
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, ну вот же есть в стандарте (Object lifetime): "The lifetime of an array object starts as soon as storage with proper size and alignment is obtained, and its lifetime ends when the storage which the array occupies is reused or released."
...
Рейтинг: 0 / 0
virtual methods
    #39653420
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну то есть как только у нас есть "storage with proper size and alignment", так мы сразу можем обращаться с ним как с массивом.
...
Рейтинг: 0 / 0
virtual methods
    #39653425
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Barlonea guest, ну вот же есть в стандарте (Object lifetime): "The lifetime of an array object starts as soon as storage with proper size and alignment is obtained, and its lifetime ends when the storage which the array occupies is reused or released."Это отсюда http://eel.is/c draft/basic.life#1 ? ( "The lifetime of an object of type T begins when: storage with the proper alignment and size for type T is obtained")

Созданию объекта с помощью definition или new expression ( http://eel.is/c draft/intro.object#def:object) предшествует выделение storage под этот объект. lifetime у достаточно тривиально конструируемых типов начинается сразу при выделении storage. Важно то, что выделение storage происходит в рамках definition объекта или new expression.

Это неправильно понимать как то, что объекты сами собой заводятся в произвольном storage подходящего для них размера и выравнивания. Так многие думают (я тоже так когда-то интерпретировал это место), но тут это не имеется в виду.
...
Рейтинг: 0 / 0
virtual methods
    #39653427
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barlone, как же тогда быть с обычными Си строками на куче, те, что с завершающим нулём? Чтобы получить размер массива символов строки, нам нужно вызвать strlen, передав ей указатель на первый символ строки, а strlen, по заверениям некоторых товарищей, реализована с UB, так как строка не была создана как массив символов через new placement в недрах libstdc++ библиотеки - нельзя, ататашеньки! :)
...
Рейтинг: 0 / 0
virtual methods
    #39653429
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestBarlonea guest, ну вот же есть в стандарте (Object lifetime): "The lifetime of an array object starts as soon as storage with proper size and alignment is obtained, and its lifetime ends when the storage which the array occupies is reused or released."Это отсюда http://eel.is/c draft/basic.life#1 ? ( "The lifetime of an object of type T begins when: storage with the proper alignment and size for type T is obtained")

Созданию объекта с помощью definition или new expression ( http://eel.is/c draft/intro.object#def:object) предшествует выделение storage под этот объект. lifetime у достаточно тривиально конструируемых типов начинается сразу при выделении storage. Важно то, что выделение storage происходит в рамках definition объекта или new expression.

Это неправильно понимать как то, что объекты сами собой заводятся в произвольном storage подходящего для них размера и выравнивания. Так многие думают (я тоже так когда-то интерпретировал это место), но тут это не имеется в виду.Объекты не заводятся, но массив - это не объект.
...
Рейтинг: 0 / 0
virtual methods
    #39653432
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как только выделили память, появился массив... но объектов в этом массиве нет, пока не вызвали placenent new
...
Рейтинг: 0 / 0
virtual methods
    #39653437
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BarloneКак только выделили память, появился массив... но объектов в этом массиве нет, пока не вызвали placenent newТо есть я не имею права делать так?:
Код: plaintext
1.
2.
3.
4.
5.
6.
static const char* test[] = "The test message";
size_t sz = std::strlen(test);
char* cstr_ptr = std::malloc(++sz);
if (NULL == cstr_ptr)
  throw std::bad_alloc;
std::strncpy(cstr_ptr, test, sz);

Ведь это же сплошной, тотальный UB!!! :)
...
Рейтинг: 0 / 0
virtual methods
    #39653439
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BarloneКак только выделили память, появился массив... но объектов в этом массиве нет, пока не вызвали placenent newИ что есть "объект" в понимании стандарта С++?
...
Рейтинг: 0 / 0
virtual methods
    #39653448
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Barloneмассив - это не объект.ШТО?!
BarloneКак только выделили память, появился массив...Какого типа?
...
Рейтинг: 0 / 0
virtual methods
    #39653657
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barlonea guestПока там не создан массив с помощью placement new — нельзя.Интересная точка зрения. И главное, я не могу найти в стандарте ее опровержения. А есть какие-нибудь обсуждения, комментарии по этому поводу (кроме этой темы)?Это потому, что очень многие никогда не читают "Введение" .
...
Рейтинг: 0 / 0
virtual methods
    #39653724
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Barloneну вот же есть в стандарте (Object lifetime): "The lifetime of an array object startsЧерез 20 минут:Barloneмассив - это не объект.
...
Рейтинг: 0 / 0
virtual methods
    #39653736
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, тебе уже ответили, что есть элемент массива, а что есть объект, но ты привычно не читаешь. 21457288

Когда выражение, имеющее целочисленный тип прибавлено или вычтено из указателя, результат имеет тип операнда указателя. Если операнд указателя указывает на объект элемента массива и массив достаточно велик, результат указывает на смещение элемента от начального элемента так, что разница индексов результирующего и начального элемента массива является целочисленным выражением. Иными словами, если выражение P указывает на i-тый объект элемента массива, выражение (P)+N (в арифметике указателей тоже, что N+(P)) и (P)-N (где N имеет значение n) указывают, соответственно, на i+n-ый и i-n-ый объект элементов массива, если они существуют. Более того, если выражение P указывает на объект последнего элемента массива, выражение (P)+1 указывает следующий объект элемента массива после последнего и если выражение Q указывает на следующий за последним объектом элемента массива, выражение (Q)-1 указывает на последний объект элемента массива. Если оба, и операнд указателя, и результат также указывают на объект массива или на следующий за последним объект элемента массива, результатом оценки выражения не должно являться переполнение, в противном случае, поведение не определено. Если результат указывает на следующий за последним объект элемента массива, этот результат не должен быть использован в качестве операнда унарного оператора * (разыменование указателя).

Примечание: Здесь под элементом массива понимается некая абстрактная единица хранения массива, имеющая размер хранящегося в ней объекта, а под объектом элемента понимается экземпляр любого типа, хранящийся в элементе массива, а не только экземпляр какого-либо класса.
...
Рейтинг: 0 / 0
virtual methods
    #39653754
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devBarloneпропущено...
Интересная точка зрения. И главное, я не могу найти в стандарте ее опровержения. А есть какие-нибудь обсуждения, комментарии по этому поводу (кроме этой темы)?Это потому, что очень многие никогда не читают "Введение" .Введение — это не нормативная часть стандарта. (Читай: она ничего не значит)
rdb_deva guest, тебе уже ответили, что есть элемент массива, а что есть объектГде?
rdb_dev 21457288 Это из стандарта C. И это не определение массива или объекта. Это про адресную арифметику.
...
Рейтинг: 0 / 0
virtual methods
    #39653785
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devпропущено...
Это потому, что очень многие никогда не читают "Введение" .Введение — это не нормативная часть стандарта. (Читай: она ничего не значит)По-твоему, это "ничего не значит"? :)
C++ is a general purpose programming language based on the C programming language as described in ISO/IEC 9899:2011 Programming languages — C (hereinafter referred to as the C standard). C++ provides many facilities beyond those provided by C, including additional data types, classes, templates, exceptions, namespaces, operator overloading, function name overloading, references, free store management operators, and additional library facilities. Ну конечно, народ же это просто от балды написал! Ясно-понятно...

a guestrdb_deva guest, тебе уже ответили, что есть элемент массива, а что есть объектГде?В той части женского тела, которая привычно рифмуется с вопросом "Где?"! :) Глаза разуй!

a guestrdb_dev 21457288 Это из стандарта C. И это не определение массива или объекта. Это про адресную арифметику.Конечно! Что же еще?
...
Рейтинг: 0 / 0
virtual methods
    #39653792
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Введение — это не нормативная часть стандарта. (Читай: она ничего не значит)По-твоему, это "ничего не значит"?Не по моему, а по правилам написания стандартов ISO.
...
Рейтинг: 0 / 0
virtual methods
    #39653793
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devПо-твоему, это "ничего не значит"?Не по моему, а по правилам написания стандартов ISO.Ok! Правила в студию!

А это тебе почитать на досуге про индексы массивов и арифметику указателей .
...
Рейтинг: 0 / 0
virtual methods
    #39653796
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Не по моему, а по правилам написания стандартов ISO.Ok! Правила в студию!Тот кто утверждает чушь и должен работать доказывая свои утверждения.
...
Рейтинг: 0 / 0
virtual methods
    #39653802
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, давай-ка почитаем перевод, идеально сделанный yandex переводчиком без каких-либо моих правок, чтоб тебе было понятней, что там написано.
ОригиналC++ is a general purpose programming language based on the C programming language as described in ISO/IEC 9899:2011 Programming languages — C (hereinafter referred to as the C standard). C++ provides many facilities beyond those provided by C, including additional data types, classes, templates, exceptions, namespaces, operator overloading, function name overloading, references, free store management operators, and additional library facilities.
ПереводC++ - это язык программирования общего назначения, основанный на языке программирования C, как описано в ISO/IEC 9899:2011 Programming languages — C (далее-стандарт C). C++ предоставляет множество возможностей, помимо предоставляемых C, включая дополнительные типы данных, классы, шаблоны, исключения, пространства имен, перегрузку операторов, перегрузку имен функций, ссылки, операторы управления свободными хранилищами и дополнительные библиотечные средства.
Комментарии излишни.
...
Рейтинг: 0 / 0
virtual methods
    #39653807
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_deva guestrdb_devПо-твоему, это "ничего не значит"?Не по моему, а по правилам написания стандартов ISO.Ok! Правила в студию!Тот кто утверждает чушь и должен работать доказывая свои утверждения.Так ты и утверждаешь тут какую-то чушь про правила написания стандартов. Утверждаешь - доказывай!
...
Рейтинг: 0 / 0
virtual methods
    #39653812
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Тот кто утверждает чушь и должен работать доказывая свои утверждения.Так ты и утверждаешь тут какую-то чушь про правила написания стандартов.Нет, это не чушь, а чистая правда.
Раз я не утверждаю чушь, то и доказывать не должен.
...
Рейтинг: 0 / 0
virtual methods
    #39653819
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devпропущено...
Так ты и утверждаешь тут какую-то чушь про правила написания стандартов.Нет, это не чушь, а чистая правда.
Раз я не утверждаю чушь, то и доказывать не должен.Ну так и доказывай, что это "чистая правда" - приведи ссылку на тот фрагмент правил написания стандартов ISO где утверждается, то, что ты тут нам пересказываешь! :)
...
Рейтинг: 0 / 0
virtual methods
    #39653825
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Нет, это не чушь, а чистая правда.
Раз я не утверждаю чушь, то и доказывать не должен.Ну так и доказывай, что это "чистая правда"Это ты меня пытаешься в чём-то убедить (что в C++ действительно всё то, что действительно в C, т.к. C++ наследуется от C или вроде того). Ну вот и доказывай, что Введение к чему-то обязывает.
...
Рейтинг: 0 / 0
virtual methods
    #39653832
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devНу так и доказывай, что это "чистая правда"Это ты меня пытаешься в чём-то убедить (что в C++ действительно всё то, что действительно в C, т.к. C++ наследуется от C или вроде того). Ну вот и доказывай, что Введение к чему-то обязывает.Неа! :) Я просто хочу увидеть ссылку на тот фрагмент официальных правил написания стандартов ISO где утверждается, то, что ты тут нам пересказываешь!
...
Рейтинг: 0 / 0
virtual methods
    #39653844
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Это ты меня пытаешься в чём-то убедить (что в C++ действительно всё то, что действительно в C, т.к. C++ наследуется от C или вроде того). Ну вот и доказывай, что Введение к чему-то обязывает.Неа! :) Я просто хочу увидеть ссылку на тот фрагмент официальных правил написания стандартов ISO где утверждается, то, что ты тут нам пересказываешь!И кто тебе мешает?
...
Рейтинг: 0 / 0
virtual methods
    #39653877
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devНеа! :) Я просто хочу увидеть ссылку на тот фрагмент официальных правил написания стандартов ISO где утверждается, то, что ты тут нам пересказываешь!И кто тебе мешает?Твой "Чайник Рассела", очевидно же!
Бремя доказательства лежит на утверждающем.
...
Рейтинг: 0 / 0
virtual methods
    #39653902
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
И кто тебе мешает?Твой "Чайник Рассела", очевидно же!
Бремя доказательства лежит на утверждающем.Это ты пытаешься тут доказать про действие правил из C в C++.
...
Рейтинг: 0 / 0
virtual methods
    #39653937
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Это ты пытаешься тут доказать про действие правил из C в C++.Мне не надо ничего доказывать! За меня это сделало "Введение в стандарт C++" 21460144 .Там даже не написано такого (что правила действуют).
Написано, что C++ "based" на C. Что это "based" означает? Java тоже based на C и C++.
...
Рейтинг: 0 / 0
virtual methods
    #39653941
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestТам даже не написано такого (что правила действуют).
Написано, что C++ "based" на C. Что это "based" означает? Java тоже based на C и C++.Перечитывай до просветления, может излечишься!
"C++ - это язык программирования общего назначения, основанный на языке программирования C, как описано в ISO/IEC 9899:2011 Programming languages — C (далее-стандарт C). C++ предоставляет множество возможностей, помимо предоставляемых C, включая дополнительные типы данных, классы, шаблоны, исключения, пространства имен, перегрузку операторов, перегрузку имен функций, ссылки, операторы управления свободными хранилищами и дополнительные библиотечные средства."
...
Рейтинг: 0 / 0
virtual methods
    #39653944
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestНаписано, что C++ "based" на C. Что это "based" означает? Java тоже based на C и C++.В каком месте спецификации Java написана подобная бредятина? Можно ссылочку?
...
Рейтинг: 0 / 0
virtual methods
    #39653947
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestТам даже не написано такого (что правила действуют).
Написано, что C++ "based" на C. Что это "based" означает? Java тоже based на C и C++.Перечитывай до просветления, может излечишься!
"C++ - это язык программирования общего назначения, основанный на языке программирования C, как описано в ISO/IEC 9899:2011 Programming languages — C (далее-стандарт C). C++ предоставляет множество возможностей, помимо предоставляемых C, включая дополнительные типы данных, классы, шаблоны, исключения, пространства имен, перегрузку операторов, перегрузку имен функций, ссылки, операторы управления свободными хранилищами и дополнительные библиотечные средства." А почему тогда, например, variable length arrays в C++ не разрешены? Они разрешены в C, на котором C++ based (что, якобы, должно означать, что всё, что верно в C — верно и в C++).
...
Рейтинг: 0 / 0
virtual methods
    #39653958
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestА почему тогда, например, variable length arrays в C++ не разрешены? Они разрешены в C, на котором C++ based (что, якобы, должно означать, что всё, что верно в C — верно и в C++).С какого перепугу? :)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
  for (UINT i = 1; i < 100; i++)
  {
    int sz = std::rand() & 0x0F;
    if (!sz) sz = 16;
    double a[sz];
    printf("Byte size of array: %llu\r\n", (size_t)sizeof(a));
  }
...
Рейтинг: 0 / 0
virtual methods
    #39653966
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyЯ вообще не понимаю, какая джава головного мозга должна быть в голове человека, предположившего, что работа с памятью через приведенный указатель в С/С++ это UB (т.е. то без чего С/С++ нафик не нужен еще и не работает).
Тут не стандарт надо обсуждать, а куда его направить лечиться ))

но в целом-то он прав. Лично я, всю жизнь думал, что арифметика над указателями описывается просто как pointer + sizeof( type ). Но драфт на который была ссылка (ровно как и MSDN) арифметику над указателями описывает __исключительно__ как навигацию в массиве (при этом исключительно в приделах массива, с исключением для элемента следующего за самым последним). Т.ч. в данном случае "java головного мозга" у тех, кто пишет драфты пытаясь из C сделать нечто java-ООП-универсально-образное.

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

То, что char и int все же формально разные типы данных, надеюсь никто спорить не будет.

IMHO & AFAIK

P.S. Топик получился феерический. Вроде начался с одного невинного идиотского вопроса, а уже 13 страниц все друг в друга какашки кидают. На мой взгляд, топик нужно занести в аналы истории, где-то рядом с темой "бритье подмышек" из fido конференции )))
...
Рейтинг: 0 / 0
virtual methods
    #39653969
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestЯ вижу ты совсем нулевой...
https://wandbox.org/permlink/SrXdy1eWXerw4BGL
Код: plaintext
1.
2.
error: ISO C++ forbids variable length array 'a' [-Wvla]
     double a[sz];
                ^
Ты можешь мне не верить, но я собрал свой код на свежем компиляторе g++, который, де-факто, является стандартом среди компиляторов C++, с указанием стандарта C++11 и выполнил полученный бинарный исполняемый модуль получив ожидаемый результат. Можешь смело потерять ссылку на ту байду, в которой проверяешь ты.
...
Рейтинг: 0 / 0
virtual methods
    #39653978
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestЯ вижу ты совсем нулевой...
https://wandbox.org/permlink/SrXdy1eWXerw4BGL
Код: plaintext
1.
2.
error: ISO C++ forbids variable length array 'a' [-Wvla]
     double a[sz];
                ^
Ты можешь мне не верить, но я собрал свой код на свежем компиляторе g++ https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html Variable-length automatic arrays are allowed in ISO C99, and as an extension GCC accepts them in C90 mode and in C++ .
Передай своему свежему g++ флаг -pedantic-errors
...
Рейтинг: 0 / 0
virtual methods
    #39653990
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevЛично я, всю жизнь думал, что арифметика над указателями описывается просто как pointer + sizeof( type ).Ты неправильно думал! То, о чем ты думал, отсутствует также и в Си. Арифметика указателей всегда учитывает размер типа данных на экземпляры которых ссылается указатель. Если указатель указывает на double, то (P)+1 указывает на следующий double, а не на более старший байт (для little-endian) или более младший (для big-endian) байт того же самого double.

Leonid KudryavtsevНо драфт на который была ссылка (ровно как и MSDN) арифметику над указателями описывает __исключительно__ как навигацию в массиве (при этом исключительно в приделах массива, с исключением для элемента следующего за самым последним). Т.ч. в данном случае "java головного мозга" у тех, кто пишет драфты пытаясь из C сделать нечто java-ООП-универсально-образное.Вот что об этом написано в стандарте C++ . Ничем не отличается от Си.

Leonid KudryavtsevВ общем-то, "работа с памятью через приведенный указатель не к исходному типу", явно платформенно зависимое решение, которое может работать, а может и нет.Тут ты тоже ошибаешься.
...
Рейтинг: 0 / 0
virtual methods
    #39653991
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestПередай своему свежему g++ флаг -pedantic-errorsПередал, ничего не поменялось! :)
...
Рейтинг: 0 / 0
virtual methods
    #39653995
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_deva guestПередай своему свежему g++ флаг -pedantic-errorsПередал, ничего не поменялось! :)А нет, пардон! Поменялось.
Ну и зачем мне выставлять этот флаг? :)
...
Рейтинг: 0 / 0
virtual methods
    #39653996
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devrdb_devпропущено...
Передал, ничего не поменялось! :)А нет, пардон! Поменялось.
Ну и зачем мне выставлять этот флаг? :)Чтобы отключить нестандартные расширения. VLA — это расширение g++. VLA не разрешены стандартом.
...
Рейтинг: 0 / 0
virtual methods
    #39654002
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devпропущено...
А нет, пардон! Поменялось.
Ну и зачем мне выставлять этот флаг? :)Чтобы отключить нестандартные расширения. VLA — это расширение g++. VLA не разрешены стандартом.Кто тебе сказал, что это поведение "нестандартное"? :) Тебе же гнусы чёрным по белому написали:
"Variable-length automatic arrays are allowed in ISO C99, and as an extension GCC accepts them in C90 mode and in C++."

Надеюсь, тебе не надо объяснять, что означают сокращения C99 и C90 ?
...
Рейтинг: 0 / 0
virtual methods
    #39654006
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Чтобы отключить нестандартные расширения. VLA — это расширение g++. VLA не разрешены стандартом.Кто тебе сказал, что это поведение "нестандартное"? :) Тебе же гнусы чёрным по белому написали:
"Variable-length automatic arrays are allowed in ISO C99, and as an extension GCC accepts them in C90 mode and in C++."

Надеюсь, тебе не надо объяснять, что означают сокращения C99 и C90 ?Ты не отличаешь C99 от C++?
...
Рейтинг: 0 / 0
virtual methods
    #39654007
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Чтобы отключить нестандартные расширения. VLA — это расширение g++. VLA не разрешены стандартом.Кто тебе сказал, что это поведение "нестандартное"? :) Тебе же гнусы чёрным по белому написали: "error: ISO C++ forbids variable length array".
...
Рейтинг: 0 / 0
virtual methods
    #39654018
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devпропущено...
Кто тебе сказал, что это поведение "нестандартное"? :) Тебе же гнусы чёрным по белому написали: "error: ISO C++ forbids variable length array". Это означает лишь одно - в стандарте C++ явно оговорили данное отличие от наследуемого Си. Что тебя, опять, не устраивает?
...
Рейтинг: 0 / 0
virtual methods
    #39654024
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev....Арифметика указателей всегда учитывает размер типа данных на экземпляры которых ссылается указатель.....
Об этом я знаю ))) sizeof(type) я и написал.

Но draf то опысывает как раз по другому. Не "учитывается размер", а то, что будет выбран корректный элемент в массиве. Т.е. ограничивает всю "арифметику" исключительно перемещением по массиву (при этом, еще и с запретом выхода за пределы массива)
...
Рейтинг: 0 / 0
virtual methods
    #39654025
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
"error: ISO C++ forbids variable length array". Это означает лишь одно - в стандарте C++ явно оговорили данное отличие от наследуемого Си. Ты вроде был за то, что VLA разрешены. Allowed красным выделял.
В каком разделе стандарта C++ явно оговорено данное отличие?
...
Рейтинг: 0 / 0
virtual methods
    #39654029
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devпропущено...
Это означает лишь одно - в стандарте C++ явно оговорили данное отличие от наследуемого Си. Ты вроде был за то, что VLA разрешены. Allowed красным выделял.
В каком разделе стандарта C++ явно оговорено данное отличие?Тебе гнусы написали, что VLA разрешены в C90 режиме компилятора g++. Чего тебе еще?
...
Рейтинг: 0 / 0
virtual methods
    #39654030
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsevно в целом-то он прав. Лично я, всю жизнь думал, что арифметика над указателями описывается просто как pointer + sizeof( type ). Но драфт на который была ссылка (ровно как и MSDN) арифметику над указателями описывает __исключительно__ как навигацию в массиве (при этом исключительно в приделах массива, с исключением для элемента следующего за самым последним).
Кусок памяти и ссылка (в широком смысле: имя, указатель, ссылка) на него с информацией о типе, это и есть объект, в том числе массив, если тип - массив. Абсолютно не важно какие там конструкторы и в каком порядке вызывались. От этого массив не перестает быть массивом. Если конструктор не вызван, то объект просто неинициализированный, обращение к его содержимому - UB. Если нет такого обращения, то никакого UB нет. Нет никакого правила, что все элементы массива должны быть инициализированы при создании массива, а иначе это не массив.

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

Все остальный фантазии прозвучавшие в этом топике про то что "массива нет" - бред сивой кобылы.
...
Рейтинг: 0 / 0
virtual methods
    #39654032
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Ты вроде был за то, что VLA разрешены. Allowed красным выделял.
В каком разделе стандарта C++ явно оговорено данное отличие?Тебе гнусы написали, что VLA разрешены в C90 режиме компилятора g++.Ты совсем недавно писал, что C это часть стандарта C++ и поэтому в C++ разрешены VLA. Даже демонстрировал код, который якобы должен был это подтвердить.
rdb_devЧего тебе еще?Покажи, где стандарт C++ явно оговорил запрет VLA.
...
Рейтинг: 0 / 0
virtual methods
    #39654036
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devЧего тебе еще?Покажи, где стандарт C++ явно оговорил запрет VLA.Не знаю... Может ты мне подскажешь, в каком месте стандарта C++ указано что VLA - forbids?
Компилятор g++, без дурацких параметров командной строки собирает и не жужжит...
...
Рейтинг: 0 / 0
virtual methods
    #39654038
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevНо draf то опысывает как раз по другому. Не "учитывается размер", а то, что будет выбран корректный элемент в массиве. Т.е. ограничивает всю "арифметику" исключительно перемещением по массиву (при этом, еще и с запретом выхода за пределы массива)Ничего подобного!
http://eel.is/c++draft/expr.post#expr.sub]The expression E1[E2] is identical (by definition) to *((E1)+(E2)), except that in the case of an array operand, the result is an lvalue if that operand is an lvalue and an xvalue otherwise.
...
Рейтинг: 0 / 0
virtual methods
    #39654052
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devrdb_devпропущено...
Это означает лишь одно - в стандарте C++ явно оговорили данное отличие от наследуемого Си. Что тебя, опять, не устраивает? Не знаю... Может ты мне подскажешь, в каком месте стандарта C++ указано что VLA - forbids?Прям явно — нигде такого не написано. По крайней мере я не находил такого.
...
Рейтинг: 0 / 0
virtual methods
    #39654056
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devНе знаю... Может ты мне подскажешь, в каком месте стандарта C++ указано что VLA - forbids?Прям явно — нигде такого не написано. По крайней мере я не находил такого.Удивляешь ты меня раз за разом...
11.3.4
...
Рейтинг: 0 / 0
virtual methods
    #39654059
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Прям явно — нигде такого не написано. По крайней мере я не находил такого.Удивляешь ты меня раз за разом...
11.3.4 Ты понимаешь слово "явно"? Неявно оно следует из ограничения на выражение, задающее размер. Которое должно быть константным.
"Явно" — это если бы в http://eel.is/c draft/diff.iso (This subclause lists the differences between C++ and ISO C) явно написали, что VLA в C++ нет, хотя они есть в C.
...
Рейтинг: 0 / 0
virtual methods
    #39654062
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestТы понимаешь слово "явно"? Неявно оно следует из ограничения на выражение, задающее размер. Которое должно быть константным.
"Явно" — это если бы в http://eel.is/c draft/diff.iso (This subclause lists the differences between C++ and ISO C) явно написали, что VLA в C++ нет, хотя они есть в C.То есть D1 [constant-expression] attribute-specifier-seq это недостаточно явно, ага?
...
Рейтинг: 0 / 0
virtual methods
    #39654065
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestТы понимаешь слово "явно"? Неявно оно следует из ограничения на выражение, задающее размер. Которое должно быть константным.
"Явно" — это если бы в http://eel.is/c draft/diff.iso (This subclause lists the differences between C++ and ISO C) явно написали, что VLA в C++ нет, хотя они есть в C.То есть D1 [constant-expression] attribute-specifier-seq это недостаточно явно, ага?То есть An object is created by a definition ([basic.def]), by a new-expression, when implicitly changing the active member of a union ([class.union]), or when a temporary object is created ([conv.rval], [class.temporary]) это недостаточно явно говорит о том, что malloc не создаёт объекты и что массивы не самозарождаются?
...
Рейтинг: 0 / 0
virtual methods
    #39654090
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что-то раздухарились вы на 14 страниц...
Там есть что-то интересное?
...
Рейтинг: 0 / 0
virtual methods
    #39654103
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уже нет.
Даже лагеря сохраняют состав.
...
Рейтинг: 0 / 0
virtual methods
    #39654247
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЧто-то раздухарились вы на 14 страниц...
Там есть что-то интересное?вечером под попкорн можно почитать ))
...
Рейтинг: 0 / 0
virtual methods
    #39654267
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv, свист банхаммера ласкает ухо. Заржавел поди твой инструмент?
...
Рейтинг: 0 / 0
virtual methods
    #39654398
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestэто недостаточно явно говорит о том, что malloc не создаёт объекты и что массивы не самозарождаются?Библиотечная функция malloc и в Си никогда не создавала объекты...Её задача - выделение из кучи участка запрошенного размера. Не больше, не меньше.

Массив переменной длины на стеке. Код без проблем компилируется с флагом -pedantic-errors
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
  std::srand(time(0));
  size_t sz = (int)std::rand() & 0x1F;
  if (!sz) sz = 16;
  PINT32 t, e, a = (PINT32)alloca(sz<<2);
  if (NULL == a)
    throw new std::bad_alloc();
  e = a + sz;
  t = a;
  while (t < e)
    *(t++) = std::rand() - ((int)RAND_MAX>>1);
  for (int i = 0; i < sz; i++)
    printf("a[%i] = %i\r\n", i, a[i]);
...
Рейтинг: 0 / 0
virtual methods
    #39654409
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestэто недостаточно явно говорит о том, что malloc не создаёт объекты и что массивы не самозарождаются?Библиотечная функция malloc и в Си никогда не создавала объекты...Её задача - выделение из кучи участка запрошенного размера. Не больше, не меньше.

Массив переменной длины на стеке.Тут нет массива.
...
Рейтинг: 0 / 0
virtual methods
    #39654410
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestТут нет массива.И с чего ты это взял?
Тебе же в стандарте явно указано: The expression E1[E2] is identical (by definition) to *((E1)+(E2))
...
Рейтинг: 0 / 0
virtual methods
    #39654412
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestТут нет массива.И с чего ты это взял?С того, что его там нет.
rdb_devТебе же в стандарте явно указано: The expression E1[E2] is identical (by definition) to *((E1)+(E2)) Ну и?
...
Рейтинг: 0 / 0
virtual methods
    #39654413
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestНу и?
Если элемент массива эквивалентен типизированному указателю, то функция, возвращающая некую область памяти затребованного размера по нетипизированному указателю уже является неинициализированным массивом объектов элементов массива того типа указателя, через который, в конечном итоге, будет осуществляться доступ к этой области памяти.
...
Рейтинг: 0 / 0
virtual methods
    #39654414
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestНу и?Ну и включи логику и сделай выводы!
Если элемент массива эквивалентен типизированному указателю, то функция, возвращающая некую область памяти затребованного размера по нетипизированному указателю уже является неинициализированным массивом объектов элементов массива того типа указателя, через который, в конечном итоге, будет осуществляться доступ к этой области памяти.Только вот элемент массива не эквивалентен типизированному указателю.
...
Рейтинг: 0 / 0
virtual methods
    #39654419
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestТолько вот элемент массива не эквивалентен типизированному указателю.Еще раз: http://eel.is/c++draft/expr.post#expr.sub]The expression E1[E2] is identical (by definition) to *((E1)+(E2))
...
Рейтинг: 0 / 0
virtual methods
    #39654421
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Друзья! Убедительная просьба - обсуждать тему а не собеседника.

Учитесь быть деликатными. Попробуйте. У вас получится.
...
Рейтинг: 0 / 0
virtual methods
    #39654422
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestТолько вот элемент массива не эквивалентен типизированному указателю.Еще раз: http://eel.is/c++draft/expr.post#expr.sub]The expression E1[E2] is identical (by definition) to *((E1)+(E2)) Ещё раз: ну и?
...
Рейтинг: 0 / 0
virtual methods
    #39654424
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestЕщё раз: ну и? http://eel.is/c++draft/expr.post#expr.sub] The expression E1[E2] is identical (by definition) to *((E1)+(E2))
...
Рейтинг: 0 / 0
virtual methods
    #39654425
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestЕщё раз: ну и? http://eel.is/c++draft/expr.post#expr.sub] The expression E1[E2] is identical (by definition) to *((E1)+(E2)) Ну и?
...
Рейтинг: 0 / 0
virtual methods
    #39654427
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, 21463609
...
Рейтинг: 0 / 0
virtual methods
    #39654428
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev, a guest,

У вас deadlock
...
Рейтинг: 0 / 0
virtual methods
    #39654429
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guest, 21463609 В том, на чём тебя заело, не написано про эквивалентность элемента массива указателю.
...
Рейтинг: 0 / 0
virtual methods
    #39654430
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestВ том, на чём тебя заело, не написано про эквивалентность элемента массива указателю.тогда поясни, что, по-твоему, там написано.
...
Рейтинг: 0 / 0
virtual methods
    #39654432
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestВ том, на чём тебя заело, не написано про эквивалентность элемента массива указателю.тогда поясни, что, по-твоему, там написано.Там написано, что выражение E1[E2] эквивалентно (по определению) выражению *((E1)+(E2)). (За некоторыми исключениями, которые потерялись.)
Тебе не ясно, что значит "эквивалентно по определению"?
...
Рейтинг: 0 / 0
virtual methods
    #39654433
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, мне-то абсолютно ясно, что значит "эквивалентно (по определению) выражению *((E1)+(E2))", наверное потому, что я хорошо понимаю смысл записи:
*((E1)+(E2))
...
Рейтинг: 0 / 0
virtual methods
    #39742193
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Предлагаю всем великим знатокам грамматики пройти и посмотреть, как сейчас выглядит http://eel.is/c draft/expr.add#4 :

When an expression J that has integral type is added to or subtracted from an expression P of pointer type, the result has the type of P.
— If P evaluates to a null pointer value and J evaluates to 0, the result is a null pointer value.
— Otherwise, if P points to element x[i] of an array object x with n elements,82 the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i+j] if 0≤i+j≤n and the expression P - J points to the (possibly-hypothetical) element x[i−j] if 0≤i−j≤n.
— Otherwise, the behavior is undefined.

По-прежнему будете бредить, что последний "Otherwise" относится только к "if 0≤i−j≤n", а не обоим предыдущим пунктам?
...
Рейтинг: 0 / 0
virtual methods
    #39749003
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, и что это меняет? Ты сам-то хорошо разобрался в том, что написано и внимательно ли ты с самого начала читал стандарт?
http://eel.is/c draft/intro.defs#defns.access
...
Рейтинг: 0 / 0
virtual methods
    #39754230
a.guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guest, и что это меняет?Формально это ничего не меняет, просто переформатировали параграф и перенесли пункт, разрешающий прибавлять к нулевому указателю 0 повыше, так, чтобы это не противоречило тому, что в одном месте говорят, что "...; иначе UB", а через пару параграфов есть иначе, которое не UB. Параграф, разрешающий добавлять 0 к нулевому указателю ввели в C++, в C его нет, и забыли обновить параграф, оставшийся от C.

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


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