?

Log in

No account? Create an account

It's that time of year again... - Общество дровосеков Бердичева по изучению Мишны

Sep. 30th, 2014

10:03 pm - It's that time of year again...

Previous Entry Share Next Entry

Не перевелись еще любители http://ioccc.org/ ? У вас есть еще некоторое время до закрытия конкурса.

Comments:

[User Picture]
From:fatoff
Date:October 1st, 2014 06:09 am (UTC)
(Link)
Это конечно, серьёзное упражнение для мозга. :)
Но практически бесполезное на фоне полезных. :)

Вот для примера, на 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 at 2014-10-01 06:14 am (UTC)
(Reply) (Thread)
[User Picture]
From:archaicos
Date:October 1st, 2014 06:32 am (UTC)

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

(Link)
Точку с запятой забыл!
:)
(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:October 1st, 2014 06:33 am (UTC)
(Link)
Почему-то никто за все эти годы так и не организовал конкурс Obfuscated C++. Возможно, потому, что разбираться в нем гораздо сложнее, чем в Си.

От написания программ на конкурс пользы, может быть, и немного (хотя победителям добавляет славы), а от рассматривания победителей конкурса польза вполне есть.
(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:October 1st, 2014 06:36 am (UTC)
(Link)
Чего ж тут WTF, всё логично и по плану "захотели - получили". А вот как скопом запретить в классе copy-конструкторы из классов-потомков, я не знаю.
(Reply) (Parent) (Thread)
[User Picture]
From:fatoff
Date:October 1st, 2014 06:49 am (UTC)
(Link)
Ну вот, ты раскрыл отсутствие WTF. Для меня это и был WTF.
А контейнер имеет пустой-никчёмный тип ячейки.

А если б ты вёз макароны?
А если то был вектор?
(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:October 1st, 2014 06:56 am (UTC)
(Link)
Какая разница? Если для чего-то, не связанного с работой с хардвером или с тонкой оптимизацией производительности уже работающего кода, надо писать cast - считай, калека.
(Reply) (Parent) (Thread)
[User Picture]
From:fatoff
Date:October 1st, 2014 03:17 pm (UTC)
(Link)
Ну дык, если не дефолтный размер элемента, то как можно напихать элементов нестандартного большего размера? Если то вектор, разумеется. Если то list, примерно представляю, почему с маленьким размером элемента не ломается...

Edited at 2014-10-01 03:17 pm (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:fatoff
Date:October 1st, 2014 05:47 pm (UTC)
(Link)
Кстати, cast написал лишь в порядке проверки на валидность типа. В этом setup'е был важен деструктор NonEmptyType.
(Reply) (Parent) (Thread)
[User Picture]
From:ak_47
Date:October 1st, 2014 11:55 pm (UTC)
(Link)
Прошу прощения за тупизну, но я не понимаю в чём WTF. Вы ожидали что они будут не равны или что будут равны?
(Reply) (Parent) (Thread)
[User Picture]
From:fatoff
Date:October 2nd, 2014 12:18 am (UTC)
(Link)
Ожидал недопустимости такой операции и чего-то вроде access fault.
(Reply) (Parent) (Thread)
[User Picture]
From:ak_47
Date:October 2nd, 2014 12:27 am (UTC)
(Link)
А, в этом смысле. Теперь понял. Ну access fault вполне может случиться, если в мембер написать что-нить. При этом, скорее всего, не сразу, а немного потом.
(Reply) (Parent) (Thread)
[User Picture]
From:dvv
Date:October 2nd, 2014 12:22 pm (UTC)
(Link)
С какого перепугу? Стандарт ясно пишет, что

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]
(Reply) (Parent) (Thread)
[User Picture]
From:fatoff
Date:October 2nd, 2014 03:06 pm (UTC)
(Link)
Это в какой-то мере про интуитивные ожидания, что такое хорошо, и что такое плохо.

Ожидал выброс при попытке доступа, естественно, где закоментировано. Ну вот, ментально ожидал, поскольку лампочка загоралась WRONG. В векторе так ещё куда более выброс вероятен, да попробовать несколько элементов. Ну, подумав за пределами собственно стандарта, и про минимальный allocation unit динамической памяти всё становится яснее. Но C++ этот код радостно хавает. Имею ввиду параметризацию контейнера пустым типом и затем присвоение на ячейку контейнера непустого потомка.
(Reply) (Parent) (Thread)
[User Picture]
From:dvv
Date:October 2nd, 2014 09:16 pm (UTC)
(Link)
Вы пишите ужасную ересь. Во-первых, C++ — это то, что прописано в его формальном описании (стандарте), и никакого "интуитивного ожидания" и "за пределами стандарта" там не бывает. Во-вторых, если бы Вы потрудились посмотреть, что такое стандартные контейнеры в C++, Вы обнаружили бы, что "пустой тип" нисколько не противоречит требованиям к элементам этих контейнеров. В-третьих, никакого "присвоения на ячейку контейнера непустого потомка" не происходит — аргумент push_back() приводится к типу элемента контейнера EmptyType (поскольку var имеет тип, производный от EmptyType, это есть корректное приведение), и результат приведения записывается в нужное место в контейнере.

Edited at 2014-10-02 09:18 pm (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:fatoff
Date:October 2nd, 2014 11:25 pm (UTC)
(Link)
Я знаю, знаю, вот вы зачем слово "интуитивно" проигнорировали? А приведение к типу контейнера как-то мало отражается на значении int m в элементе контейнера, которого в принципе не было в оригинально "пустом" типе.

Тут же про obfuscated C. А я привёл слегка obfuscated C++, не неправильный C++, примите во внимание.

Edited at 2014-10-02 11:26 pm (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:dvv
Date:October 3rd, 2014 12:55 am (UTC)
(Link)
Ась? Я явно написал, что "интуитивно" тут нет и быть не может. Какое уж тут "проигнорировал"…

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

Под obfuscated программой обычно понимается корректная программа, выдающая вполне специфицрованный результат, но трудная для интерпретации человеком. А то, что Вы привели, корректной программой не является.

Edited at 2014-10-03 12:56 am (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:fatoff
Date:October 3rd, 2014 01:17 am (UTC)
(Link)
А то, что Вы привели, корректной программой не является.

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

Не ну чо, уделали меня, уползаю зализывать раны. На всякий случай, не разоблачал я C++. Amusing case, во.
(Reply) (Parent) (Thread)