Почему-то никто за все эти годы так и не организовал конкурс Obfuscated C++. Возможно, потому, что разбираться в нем гораздо сложнее, чем в Си.
От написания программ на конкурс пользы, может быть, и немного (хотя победителям добавляет славы), а от рассматривания победителей конкурса польза вполне есть.
Какая разница? Если для чего-то, не связанного с работой с хардвером или с тонкой оптимизацией производительности уже работающего кода, надо писать cast - считай, калека.
Ну дык, если не дефолтный размер элемента, то как можно напихать элементов нестандартного большего размера? Если то вектор, разумеется. Если то list, примерно представляю, почему с маленьким размером элемента не ломается...
А, в этом смысле. Теперь понял. Ну access fault вполне может случиться, если в мембер написать что-нить. При этом, скорее всего, не сразу, а немного потом.
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]
Это в какой-то мере про интуитивные ожидания, что такое хорошо, и что такое плохо.
Ожидал выброс при попытке доступа, естественно, где закоментировано. Ну вот, ментально ожидал, поскольку лампочка загоралась WRONG. В векторе так ещё куда более выброс вероятен, да попробовать несколько элементов. Ну, подумав за пределами собственно стандарта, и про минимальный allocation unit динамической памяти всё становится яснее. Но C++ этот код радостно хавает. Имею ввиду параметризацию контейнера пустым типом и затем присвоение на ячейку контейнера непустого потомка.
Вы пишите ужасную ересь. Во-первых, C++ — это то, что прописано в его формальном описании (стандарте), и никакого "интуитивного ожидания" и "за пределами стандарта" там не бывает. Во-вторых, если бы Вы потрудились посмотреть, что такое стандартные контейнеры в C++, Вы обнаружили бы, что "пустой тип" нисколько не противоречит требованиям к элементам этих контейнеров. В-третьих, никакого "присвоения на ячейку контейнера непустого потомка" не происходит — аргумент push_back() приводится к типу элемента контейнера EmptyType (поскольку var имеет тип, производный от EmptyType, это есть корректное приведение), и результат приведения записывается в нужное место в контейнере.
Я знаю, знаю, вот вы зачем слово "интуитивно" проигнорировали? А приведение к типу контейнера как-то мало отражается на значении int m в элементе контейнера, которого в принципе не было в оригинально "пустом" типе.
Тут же про obfuscated C. А я привёл слегка obfuscated C++, не неправильный C++, примите во внимание.
Ась? Я явно написал, что "интуитивно" тут нет и быть не может. Какое уж тут "проигнорировал"…
И в элементе контейнере нет никакого элемента m. А при попытке его вытащить через reinterpret_cast может выдасться значение, которое совпадает с произвольным наперёд заданным значением, может выдасться любое другое значение, программа может рухнуть, а может начать третью мировую войну — все эти результаты прекрасно подпадают под unspecified.
Под obfuscated программой обычно понимается корректная программа, выдающая вполне специфицрованный результат, но трудная для интерпретации человеком. А то, что Вы привели, корректной программой не является.
А то, что Вы привели, корректной программой не является.
Особенно, принимая во внимание, что в оригинале у меня не было никакого reinterpret_cast. Я его умышленно сделал, чтобы подивиться на внутренности объекта.
Не ну чо, уделали меня, уползаю зализывать раны. На всякий случай, не разоблачал я C++. Amusing case, во.
no subject
Date: 2014-10-01 06:09 am (UTC)Но практически бесполезное на фоне полезных. :)
Вот для примера, на C++ произвести что-то такое:
Не компилировал, по памяти спонтанно произведённый на работе фрагмент.
А я знаю в чём дело!
Date: 2014-10-01 06:32 am (UTC):)
no subject
Date: 2014-10-01 06:33 am (UTC)От написания программ на конкурс пользы, может быть, и немного (хотя победителям добавляет славы), а от рассматривания победителей конкурса польза вполне есть.
no subject
Date: 2014-10-01 06:36 am (UTC)no subject
Date: 2014-10-01 06:49 am (UTC)А контейнер имеет пустой-никчёмный тип ячейки.
А если б ты вёз макароны?
А если то был вектор?
no subject
Date: 2014-10-01 06:56 am (UTC)no subject
Date: 2014-10-01 03:17 pm (UTC)no subject
Date: 2014-10-01 05:47 pm (UTC)no subject
Date: 2014-10-01 11:55 pm (UTC)no subject
Date: 2014-10-02 12:18 am (UTC)no subject
Date: 2014-10-02 12:27 am (UTC)no subject
Date: 2014-10-02 12:22 pm (UTC)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]
no subject
Date: 2014-10-02 03:06 pm (UTC)Ожидал выброс при попытке доступа, естественно, где закоментировано. Ну вот, ментально ожидал, поскольку лампочка загоралась WRONG. В векторе так ещё куда более выброс вероятен, да попробовать несколько элементов. Ну, подумав за пределами собственно стандарта, и про минимальный allocation unit динамической памяти всё становится яснее. Но C++ этот код радостно хавает. Имею ввиду параметризацию контейнера пустым типом и затем присвоение на ячейку контейнера непустого потомка.
no subject
Date: 2014-10-02 09:16 pm (UTC)no subject
Date: 2014-10-02 11:25 pm (UTC)Тут же про obfuscated C. А я привёл слегка obfuscated C++, не неправильный C++, примите во внимание.
no subject
Date: 2014-10-03 12:55 am (UTC)И в элементе контейнере нет никакого элемента m. А при попытке его вытащить через reinterpret_cast может выдасться значение, которое совпадает с произвольным наперёд заданным значением, может выдасться любое другое значение, программа может рухнуть, а может начать третью мировую войну — все эти результаты прекрасно подпадают под unspecified.
Под obfuscated программой обычно понимается корректная программа, выдающая вполне специфицрованный результат, но трудная для интерпретации человеком. А то, что Вы привели, корректной программой не является.
no subject
Date: 2014-10-03 01:17 am (UTC)Особенно, принимая во внимание, что в оригинале у меня не было никакого reinterpret_cast. Я его умышленно сделал, чтобы подивиться на внутренности объекта.
Не ну чо, уделали меня, уползаю зализывать раны. На всякий случай, не разоблачал я C++. Amusing case, во.