|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
rdb_dev"&((C*)0)->Get" - это что? Амперсанд (взятие адреса) видим? где здесь доступ к члену экземпляра класса (чтение свойства/вызов метода) по нулевому указателю экземпляра? Согласно стандарту, E1->E2 эквивалентно (*(E1)).E2 Таким образом "->" это в том числе и разыменование указателя. В стандарте (всех версий), разыменование нулевого указателя упоминается как пример UB. (С++17 8.3.2.5) Но в стандарте есть места противоречащие этому. Вот тут дискуссия на эту тему (она ссылается на старый стандарт, но в последнем все осталось так же) http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232 Но учитывая что как минимум одна из трактовок стандарта считает это UB и то что многие компиляторы агрессивно оптимизируют код, удаляя целые блоки кода имеющие UB, то я бы не стал такое применять в продакшене. Тем более что в VS2010 про который тут говорилось есть встроенный offsetof. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 14:50 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
Anatoly MoskovskyВ стандарте (всех версий), разыменование нулевого указателя упоминается как пример UB. (С++17 8.3.2.5).В какой версии драфта пункт 8.3.2.5? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 14:53 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky, а где написано, что нельзя разыменовывать указатель с адресом 0x0 (не путать с указателем NULL, который хоть и представлен во многих компиляторах именно как (void*)0)? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 15:12 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
rdb_devгде написано, что нельзяВ C++ так вопрос не ставится. В C++ спрашивается "где определено поведение такой-то конструкции?". А если оно не определено — то получается неопределённое поведение. rdb_devуказатель с адресом 0x0Можно узнать способ получения указателя с адресом 0x0? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 15:20 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
rdb_dev Код: plaintext 1.
http://eel.is/c draft/lex.name#3 In addition, some identifiers are reserved for use by C++ implementations and shall not be used otherwise; no diagnostic is required. — Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use . — Each identifier that begins with an underscore is reserved to the implementation for use as a name in the global namespace. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 15:25 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
a guestrdb_devуказатель с адресом 0x0Можно узнать способ получения указателя с адресом 0x0?Можно! Открой заголовочные файлы гнуса и узри в них: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Но лично я предпочитаю что-то типа: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 15:27 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
a guestrdb_dev Код: plaintext 1.
http://eel.is/c draft/lex.name#3In addition, some identifiers are reserved for use by C++ implementations and shall not be used otherwise; no diagnostic is required. — Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use . — Each identifier that begins with an underscore is reserved to the implementation for use as a name in the global namespace. Большинству разработчиков на это совершенно пофигу! Ты найдешь пренебрежение этой рекомендацией даже в исходниках RHEL, не говоря уже о заголовочных файлах реализации cstdlib. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 15:31 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
rdb_deva guestпропущено... Можно узнать способ получения указателя с адресом 0x0?Можно! Открой заголовочные файлы гнуса и узри в них: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Ну и в какой конкретно строчке получается указатель с адресом 0x0, но при этом не нулевой указатель? rdb_devНо лично я предпочитаю что-то типа: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
А тут? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 15:34 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
rdb_devТы найдешь пренебрежение этой рекомендацией даже в исходниках RHEL, не говоря уже о заголовочных файлах реализации cstdlib. 1. Стандарт резервирует идентификаторы определённого вида для реализации. 2. Реализация (в данном случае — cstdlib) использует идентификаторы данного вида. Как ты в следовании этой рекомендации смог увидеть пренебрежение ею? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 15:37 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
a guestНу и в какой конкретно строчке получается указатель с адресом 0x0, но при этом не нулевой указатель?Поясняю для непонятливых - адреса с 0x0 по 0x0000FFFF в ОС Windows для x86 являются инвалидными только благодаря самой реализации ОС, в которой при доступе по этим адресам возникает исключение page fault, но это не значит, что эти адреса инвалидны в реализациях любых ОС, в т.ч. проприетарных или в реализациях прошивок контроллеров, которые могут хранить по этим адресам некие заранее известные структуры данных по заранее известным смещениям. Поэтому, валидно любое приведение любых адресов в арифметике указателей, чтобы там не насочиняли стандартописатели. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 15:49 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
rdb_devвалидно любое приведение любых адресов в арифметике указателейМожно цитаты из стандарта? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 15:53 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
a guestrdb_devвалидно любое приведение любых адресов в арифметике указателейМожно цитаты из стандарта?Цитаты из стандарта о том, что для процессоров и контроллеров валидны все доступные им адреса памяти? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 15:59 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
rdb_devAnatoly Moskovsky, а где написано, что нельзя разыменовывать указатель с адресом 0x0 (не путать с указателем NULL, который хоть и представлен во многих компиляторах именно как (void*)0)? 4.10 параграф 1 A null pointer constant is an integer literal (2.13.2) with value zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type Т.е. число 0 при преобразовании в указатель дает нулевой указатель (независимо от того как на данной платформе реализован нулевой указатель). Таким образом (T*)0 - это нулевой указатель. a guestВ какой версии драфта пункт 8.3.2.5? n4594, 8.3.2 параграф 5 ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 16:01 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
rdb_devЦитаты из стандарта о том, что для процессоров и контроллеров валидны все доступные им адреса памяти? То что адрес 0 это такой же адрес для процессора как и другие не противоречит тому что в С++ обращение по этому адресу - UB. Из С++ обращаться к нему нельзя, а из ассемблера например можно. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 16:04 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
Anatoly Moskovskya guestВ какой версии драфта пункт 8.3.2.5? n4594, 8.3.2 параграф 5Хм. Но ведь это не Anatoly Moskovskyразыменование нулевого указателя упоминается как пример UB.Там написано что UB это инициализация ссылки выражением `*p` если `p == nullptr` (ну или вообще инициализация не валидным указателем на объект). ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 16:06 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
Anatoly Moskovskyrdb_devAnatoly Moskovsky, а где написано, что нельзя разыменовывать указатель с адресом 0x0 (не путать с указателем NULL, который хоть и представлен во многих компиляторах именно как (void*)0)? 4.10 параграф 1 A null pointer constant is an integer literal (2.13.2) with value zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type Т.е. число 0 при преобразовании в указатель дает нулевой указатель (независимо от того как на данной платформе реализован нулевой указатель). Таким образом (T*)0 - это нулевой указатель.Нет! В стандарте не сказано, что null указатель, это тоже самое, что (void*)0, хотя в некоторых компиляторах это действительно так! На эту тему было сломано немало копий именно по той простой причине, что для процессоров и контроллеров, это абсолютно реальный адрес оперативной памяти, по которому может находиться информация. Именно по этой причине в стандарт введен null указатель, который совсем не (void*)0, а именно неинициализированный указатель. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 16:06 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
a guestинициализация не валидным указателем на объектинициализация выражением, которое не обозначает валидный объект. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 16:07 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
rdb_devМожно! Открой заголовочные файлы гнуса и узри в них Внутри кода стандартной библиотеки могут быть какие угодно хаки, не всегда даже являющиеся С++. Так что не стоит оттуда брать примеры )) ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 16:14 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
a guesta guestинициализация не валидным указателем на объектинициализация выражением, которое не обозначает валидный объект.А какая разница? Представь, что ты пишешь на Си часть прошивки к контроллеру, а до тебя разработчики, что писали, к примеру boot loader на ассемблере, поместили в начальные адреса адресного пространства некие статичные инициализированные в бутстрапе структуры данных. Зная о формате этих структур, ты как к ним будешь доступ получать? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 16:15 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
Anatoly MoskovskyВнутри кода стандартной библиотеки могут быть какие угодно хаки, не всегда даже являющиеся С++. Так что не стоит оттуда брать примеры ))Без "грязных хаков" на Си/С++ системные вещи вообще не пишутся! Есть идеалисты, придумывающие стандарт, которому рекомендовано следовать, а есть программисты, которые вынуждены обходить ограничения стандартов. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 16:18 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
rdb_devНет! В стандарте не сказано, что null указатель, это тоже самое, что (void*)0 Нет конечно, там сказано что (void*)0 дает null указатель. То, с чем вы пытаетесь спорить. rdb_devИменно по этой причине в стандарт введен null указатель, который совсем не (void*)0, а именно неинициализированный указатель. Ггггг. Нет. Основная причина это корректные перегрузки функций. Со старым NULL: Код: plaintext 1. 2. 3.
С nullptr: Код: plaintext 1. 2. 3.
... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 16:24 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky, " 2.14.7 Pointer literals [lex.nullptr] pointer-literal: nullptr The pointer literal is the keyword nullptr . It is a prvalue of type std::nullptr_t . [ Note: std::nullptr_t is a distinct type that is neither a pointer type nor a pointer to member type; rather, a prvalue of this type is a null pointer constant and can be converted to a null pointer value or null member pointer value. See 4.10 and 4.11. — end note ]" Смотрим 4.10 и 4.11: " 4.10 Pointer conversions [conv.ptr] 1 A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t . A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of pointer to object or pointer to function type. Such a conversion is called a null pointer conversion. Two null pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification conversion (4.4). A null pointer constant of integral type can be converted to a prvalue of type std::nullptr_t . [ Note: The resulting prvalue is not a null pointer value. — end note ]" " 4.11 Pointer to member conversions [conv.mem] 1 A null pointer constant (4.10) can be converted to a pointer to member type; the result is the null member pointer value of that type and is distinguishable from any pointer to member not created from a null pointer constant. Such a conversion is called a null member pointer conversion. Two null member pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to member of cv-qualified type is a single conversion, and not the sequence of a pointer to member conversion followed by a qualification conversion (4.4)." Никак не могу разглядеть - в каком месте тут UB? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 16:50 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky[/src] С nullptr: Код: plaintext 1. 2. 3.
Еще не могу понять, каким образом компилятор C++ должен "дедуктировать", что тип std::nullptr_t , подходит для вызова функции void f(char*)? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 16:53 |
|
Пятничная шабонная магия
|
|||
---|---|---|---|
#18+
rdb_devНикак не могу разглядеть - в каком месте тут UB?Да никто и не говорил, что UB из-за каста нуля к указателю. Ты, похоже, вообще не понимаешь, что тебе пишут. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.04.2018, 17:35 |
|
|
start [/forum/topic.php?fid=57&msg=39624940&tid=2017587]: |
0ms |
get settings: |
8ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
51ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
56ms |
get tp. blocked users: |
1ms |
others: | 16ms |
total: | 165ms |
0 / 0 |