abbra: (Default)
[personal profile] abbra
Не хотите больше быть программистом? Оставьте свой след в истории:
http://blog.8thlight.com/dariusz-pasciak/2012/07/03/dereferencing-null-pointer-without-a-seg-fault.html

После того, как прочитали, заходите под кат и ответьте на вопрос: Скажите, а вас учили, что оператор -> над классами в C++ эквивалентен разыменованию указателя в C?

Что интересно, в стандарте С++ в 5.2.5 (Class member access) в третьем абзаце написано:
If E1 has the type “pointer to class X,” then the expression E1->E2 is converted to the equivalent form (*(E1)).E2; the remainder of 5.2.5 will address only the first option (dot).

Правда, 13.5.6 (Class member access) говорит уже более аккуратно об этом:
An expression x->m is interpreted as (x.operator->())->m for a class object x of type T if T::operator->() exists and if the operator is selected as the best match function by the overload resolution mechanism (13.3)

Date: 2012-07-11 09:53 am (UTC)
From: [identity profile] arkanoid.livejournal.com
holy shit!

Date: 2012-07-11 10:00 am (UTC)
tobotras: (Default)
From: [personal profile] tobotras
Спасибо :)

Date: 2012-07-11 10:16 am (UTC)
From: [identity profile] beldmit.livejournal.com
Я в свое время на похожее поведение уже натыкался.

http://beldmit.livejournal.com/51712.html?nc=6#comments

Оптимизация - страшная вещь.

Date: 2012-07-11 10:33 am (UTC)
From: [identity profile] beldmit.livejournal.com
Вероятно, на практике компиляторы нарушают этот пункт стандарта - потому что шанс, что будет именно описанное поведение, достаточно высок.

Date: 2012-07-11 12:12 pm (UTC)
From: [identity profile] ihar hrachyshka (from livejournal.com)
Если у вас в программе есть хотя бы одно разыменование null-поинтера, вам никто не гарантирует вообще хоть какого-либо поведения (даже запуска функции main). Ибо undefined behavior, а "раз Бога нет, то все можно".

Date: 2012-07-11 12:13 pm (UTC)
From: [identity profile] beldmit.livejournal.com
В моем случае было не разыменование, а вызов метода.

Date: 2012-07-11 12:20 pm (UTC)
From: [identity profile] ihar hrachyshka (from livejournal.com)
[C++11: 5.2.5/2]: For the first option (dot) the first expression shall have complete class type. For the second option (arrow) the first expression shall have pointer to complete class type. The expression E1->E2 is converted to the equivalent form (*(E1)).E2; the remainder of 5.2.5 will address only the first option (dot). In either case, the id-expression shall name a member of the class or of one of its base classes. [ Note: because the name of a class is inserted in its class scope (Clause 9), the name of a class is also considered a nested member of that class. —end note ] [ Note: 3.4.5 describes how names are looked up after the . and -> operators. —end note ]

Date: 2012-10-17 08:42 am (UTC)
From: [identity profile] gineer.livejournal.com
Тоже мне бином Ньютона. :))

Указатель на метод не является частью реализации объекта(структуры) класса.
Только если этот метод виртуальный и\или в нем была бы попытка обращения по this, были бы проблемы.
А так, такому удивлятся может только человек ни разу не видевший свой код в ассемблере\дебагере. :))

Date: 2012-07-11 10:19 am (UTC)
From: [identity profile] b-a-t.livejournal.com
А не (x.operator->()).m?

Date: 2012-07-11 10:21 am (UTC)
From: [identity profile] blacklion.livejournal.com
Это если этот оператор есть, о чём сообщает вторая цитата из стандарта. А если нету — просто разыменовать. А если метод не виртуальный (статическая линковка), то this не нужен. А если в методе нет обращения к виртуальным методам или не-статическим полям, то this по-прежнему не нужен и может быть любым мусором, в том числе и NULL. Всё логично, на самом деле.

Date: 2012-07-11 11:35 am (UTC)
From: [identity profile] b-a-t.livejournal.com
Не понял, к чему ты это все. Про NULL все достаточно понятно и почти ожидаемо.

Мой вопрос был про то, что operator->() должон бы возвращать T* в общем случае, в результате чего выполнялось бы выражение из первого абзаца. А две стрелочки - почти рекурсия.

Впрочем, если возвращается указатель, то -> сводится к простому типу и произойдет то самое разыменовывыние (*X).m.

Date: 2012-07-11 10:22 am (UTC)
From: [identity profile] blacklion.livejournal.com
Более того, если operatot->>() не будет трогать this, то тоже будет работать.

Date: 2012-07-11 10:20 am (UTC)
From: [identity profile] blacklion.livejournal.com
Хм... Очередная ЕЖУПА. В смысле, то, что можно разыменовывать так NULL до тех пор пока в методе нет обращения (прямого или косвенного) к this я знаю не помню сколько лет...

Date: 2012-07-11 10:35 am (UTC)
From: [identity profile] blacklion.livejournal.com
Ааа, я тебя не так понял, прошу прощения :)

Date: 2012-07-11 11:06 am (UTC)
From: [identity profile] arkanoid.livejournal.com
ну я тоже не знал. но я никогда и не претендовал на знание плюсцов более, чем требуется, чтобы разобраться в чужой программе.

хотя на текметриксе до мастера в свое время как-то дотянул, но это говорит больше про текметрикс, чем про меня.

Date: 2012-07-11 11:15 am (UTC)
From: [identity profile] arkanoid.livejournal.com
В данном случае я просто получил еще одно подтверждение того, что наука умеет много гитик, а сходство плюсцов с plain C в большинстве случаев не более, чем опасная кажимость.

Date: 2012-07-11 03:54 pm (UTC)
From: [identity profile] youngracoon.livejournal.com
Так если бы он знал, что ошибается. Ошибиться может каждый. Хотя (не будучи гуру в C/C++) могу допустить, что это что-то вопиющее...

Date: 2012-07-12 12:10 am (UTC)
From: [identity profile] luarvique.livejournal.com
Саш, народ массово не знает что после "new" следует "delete" делать, а ты про реализацию классов... Только расстреливать через "-Dnew=abort -Ddelete=nafig", да...

ресайклинг из гуд

Date: 2012-07-23 06:42 pm (UTC)
From: [identity profile] silpol.livejournal.com
главное раздобыть списки выпускников и опубликовать как кандидатов на "страшне перо не в гусака" ;)

Date: 2012-08-18 08:31 am (UTC)
From: [identity profile] just-regged.livejournal.com
Это где так происходит, простите?

Вообще, забыть сделать delete[] - это как-то более привычно.

А вообще, boost::smart_ptr спасает :)

не будучи гуру в C/C++ ...

Date: 2012-07-23 06:40 pm (UTC)
From: [identity profile] silpol.livejournal.com
... главное запомнить что это два разных языка, с разными целями создания и архитектурой, поэтому набирая в команду человека, у которого в CV написано C/C++ через слэш, нужно быть крайне осторожным и щупать его на предмет понимания что это _дваразныхязыка_ которые нечистоплотные HR и хэдхантеры лепят в один кусок. Другими словами, C/C++ в CV - это такой сигнал-к-атаке-три-зеленых-свистка.

Date: 2012-07-11 10:22 am (UTC)
From: [identity profile] poige.livejournal.com
this будет 0, и всё. IIRC.

Date: 2012-07-12 12:08 am (UTC)
From: [identity profile] luarvique.livejournal.com
Ну да. Для продвинуых x86-программеров, ECX=0 на входе в функцию член класса.

Date: 2012-07-11 07:55 pm (UTC)
From: [identity profile] ilya-dogolazky.livejournal.com
Вот этот тоже хорош http://blog.8thlight.com/kevin-liddle/2012/05/22/be-a-relentless-programmer.html --- он "learned thought patterns", извиняюсь за выражение. Ну в общем не удивительно с такой-то страничкой http://www.8thlight.com/careers

Date: 2012-07-12 12:45 am (UTC)
From: [identity profile] luarvique.livejournal.com
Вот тут самое интересное. Обращаем особое внимание на инструментарий (спойлер: С++ там конечно нет).

Date: 2012-08-18 08:32 am (UTC)
From: [identity profile] just-regged.livejournal.com
Фриков каких-то откопал, Саша :)

Date: 2012-08-18 04:17 pm (UTC)
From: [identity profile] just-regged.livejournal.com
Та ни, рубисты - они все такие. Ну, или через одного, в лучшем случае.

Мы тут пытались как-то рубиста нанять себе, редмайн под наши нужды допиливать. Поскольку опыта собеседований именно по руби у нас мало, ну, мы им попробовали давать всякие задачки из обычных собеседований: на манипулирование структурами данных, на оценку сложности задач ну и т.п. В целом, у нас очень простые задачки. Результат в целом оказался восхитительным в своей мерзости. Особо талантливых мой товарищ-начальник R&D срубал вопросом "сколько будет 2^8", но это, конечно, он со зла.
А ведь люди вполне себе работают, сайты строчат, деньги за них получают. Им просто не нужны все эти "тонкости". И не одним им, кстати. У нас и C++-программисты (ну, ладно, C++-билдер-программисты) на собеседования приходили, не умея обход дерева организовать. И ничего, трудятся.

Date: 2012-08-28 06:55 am (UTC)
From: [identity profile] ilya-dogolazky.livejournal.com
я бы наверное ответил, что 2^8 будет 10

Date: 2012-07-12 12:07 am (UTC)
From: [identity profile] luarvique.livejournal.com
Дети, ну чисто дети. И на таком ацком серьезе обьясняют, много буков, коровы, ошейники, все дела...

Ему бы за студентами ошибки в большом проекте поискать - так он бы там и не такое нашел. Правда написать об этом 5 страниц без единого матерного слова не смог бы.

к студентам не пущать

Date: 2012-07-23 06:36 pm (UTC)
From: [identity profile] silpol.livejournal.com
он же сколько невинных душ искалечит.

Date: 2012-08-18 07:08 pm (UTC)
From: [identity profile] alexey tourbin (from livejournal.com)
Вызов невиртуального метода происходит, грубо говоря, по заранее известному адресу, только неявно передается первый аргумент this=NULL. В этом же примере, если "void milk()" заменить на "virtual void milk()", то будет segmentation fault, поскольку вызов метода через VMT пойдет через нулевой указатель. Цитирование стандартов - это немного буквоедство, надо просто представлять, как эта дрянь работает. :-)

April 2016

S M T W T F S
     12
3456789
1011121314 1516
17181920212223
24252627282930

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 29th, 2025 03:26 pm
Powered by Dreamwidth Studios