spamsink: (lenin)
[personal profile] spamsink
Не перевелись еще любители http://ioccc.org/ ? У вас есть еще некоторое время до закрытия конкурса.

Date: 2014-10-01 06:09 am (UTC)
From: [identity profile] fatoff.livejournal.com
Это конечно, серьёзное упражнение для мозга. :)
Но практически бесполезное на фоне полезных. :)

Вот для примера, на C++ произвести что-то такое:

struct EmptyType {};

std::list<EmptyType> myList;

struct NonEmptyType : public EmptyType {int m;} var;

myList.push_back(var);

auto& refVar = mylist.back();

auto& refVarN = reinterpret_cast<NonEmptyType&>(refVar);

// refVarN.m == var.m // ? WTF ?


Не компилировал, по памяти спонтанно произведённый на работе фрагмент.
Edited Date: 2014-10-01 06:14 am (UTC)

А я знаю в чём дело!

Date: 2014-10-01 06:32 am (UTC)
From: [identity profile] archaicos.livejournal.com
Точку с запятой забыл!
:)

Date: 2014-10-01 06:49 am (UTC)
From: [identity profile] fatoff.livejournal.com
Ну вот, ты раскрыл отсутствие WTF. Для меня это и был WTF.
А контейнер имеет пустой-никчёмный тип ячейки.

А если б ты вёз макароны?
А если то был вектор?

Date: 2014-10-01 03:17 pm (UTC)
From: [identity profile] fatoff.livejournal.com
Ну дык, если не дефолтный размер элемента, то как можно напихать элементов нестандартного большего размера? Если то вектор, разумеется. Если то list, примерно представляю, почему с маленьким размером элемента не ломается...
Edited Date: 2014-10-01 03:17 pm (UTC)

Date: 2014-10-01 05:47 pm (UTC)
From: [identity profile] fatoff.livejournal.com
Кстати, cast написал лишь в порядке проверки на валидность типа. В этом setup'е был важен деструктор NonEmptyType.

Date: 2014-10-01 11:55 pm (UTC)
ak_47: (default)
From: [personal profile] ak_47
Прошу прощения за тупизну, но я не понимаю в чём WTF. Вы ожидали что они будут не равны или что будут равны?

Date: 2014-10-02 12:18 am (UTC)
From: [identity profile] fatoff.livejournal.com
Ожидал недопустимости такой операции и чего-то вроде access fault.

Date: 2014-10-02 12:27 am (UTC)
ak_47: (Default)
From: [personal profile] ak_47
А, в этом смысле. Теперь понял. Ну access fault вполне может случиться, если в мембер написать что-нить. При этом, скорее всего, не сразу, а немного потом.

Date: 2014-10-02 12:22 pm (UTC)
From: [identity profile] dvv.livejournal.com
С какого перепугу? Стандарт ясно пишет, что

a reference cast reinterpret_cast<T&>(x) has the same effect as the conversion *reinterpret_cast<T*>(&x) with the builtin & and * operators


И перед этим про указатели:

A pointer to an object can be explicitly converted to a pointer to an object of different type. Except that
converting an rvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types
and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type
yields the original pointer value, the result of such a pointer conversion is unspecified.
[emph. mine. dvv]

Date: 2014-10-02 03:06 pm (UTC)
From: [identity profile] fatoff.livejournal.com
Это в какой-то мере про интуитивные ожидания, что такое хорошо, и что такое плохо.

Ожидал выброс при попытке доступа, естественно, где закоментировано. Ну вот, ментально ожидал, поскольку лампочка загоралась WRONG. В векторе так ещё куда более выброс вероятен, да попробовать несколько элементов. Ну, подумав за пределами собственно стандарта, и про минимальный allocation unit динамической памяти всё становится яснее. Но C++ этот код радостно хавает. Имею ввиду параметризацию контейнера пустым типом и затем присвоение на ячейку контейнера непустого потомка.

Date: 2014-10-02 09:16 pm (UTC)
From: [identity profile] dvv.livejournal.com
Вы пишите ужасную ересь. Во-первых, C++ — это то, что прописано в его формальном описании (стандарте), и никакого "интуитивного ожидания" и "за пределами стандарта" там не бывает. Во-вторых, если бы Вы потрудились посмотреть, что такое стандартные контейнеры в C++, Вы обнаружили бы, что "пустой тип" нисколько не противоречит требованиям к элементам этих контейнеров. В-третьих, никакого "присвоения на ячейку контейнера непустого потомка" не происходит — аргумент push_back() приводится к типу элемента контейнера EmptyType (поскольку var имеет тип, производный от EmptyType, это есть корректное приведение), и результат приведения записывается в нужное место в контейнере.
Edited Date: 2014-10-02 09:18 pm (UTC)

Date: 2014-10-02 11:25 pm (UTC)
From: [identity profile] fatoff.livejournal.com
Я знаю, знаю, вот вы зачем слово "интуитивно" проигнорировали? А приведение к типу контейнера как-то мало отражается на значении int m в элементе контейнера, которого в принципе не было в оригинально "пустом" типе.

Тут же про obfuscated C. А я привёл слегка obfuscated C++, не неправильный C++, примите во внимание.
Edited Date: 2014-10-02 11:26 pm (UTC)

Date: 2014-10-03 12:55 am (UTC)
From: [identity profile] dvv.livejournal.com
Ась? Я явно написал, что "интуитивно" тут нет и быть не может. Какое уж тут "проигнорировал"…

И в элементе контейнере нет никакого элемента m. А при попытке его вытащить через reinterpret_cast может выдасться значение, которое совпадает с произвольным наперёд заданным значением, может выдасться любое другое значение, программа может рухнуть, а может начать третью мировую войну — все эти результаты прекрасно подпадают под unspecified.

Под obfuscated программой обычно понимается корректная программа, выдающая вполне специфицрованный результат, но трудная для интерпретации человеком. А то, что Вы привели, корректной программой не является.
Edited Date: 2014-10-03 12:56 am (UTC)

Date: 2014-10-03 01:17 am (UTC)
From: [identity profile] fatoff.livejournal.com
А то, что Вы привели, корректной программой не является.

Особенно, принимая во внимание, что в оригинале у меня не было никакого reinterpret_cast. Я его умышленно сделал, чтобы подивиться на внутренности объекта.

Не ну чо, уделали меня, уползаю зализывать раны. На всякий случай, не разоблачал я C++. Amusing case, во.
Page generated Mar. 7th, 2026 11:53 pm
Powered by Dreamwidth Studios