powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Пятничная шабонная магия
25 сообщений из 143, страница 4 из 6
Пятничная шабонная магия
    #39624892
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624902
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyВ стандарте (всех версий), разыменование нулевого указателя упоминается как пример UB. (С++17 8.3.2.5).В какой версии драфта пункт 8.3.2.5?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624930
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky, а где написано, что нельзя разыменовывать указатель с адресом 0x0 (не путать с указателем NULL, который хоть и представлен во многих компиляторах именно как (void*)0)?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624940
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devгде написано, что нельзяВ C++ так вопрос не ставится. В C++ спрашивается "где определено поведение такой-то конструкции?". А если оно не определено — то получается неопределённое поведение.

rdb_devуказатель с адресом 0x0Можно узнать способ получения указателя с адресом 0x0?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624949
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_dev
Код: plaintext
1.
struct __Get;


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.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624952
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devуказатель с адресом 0x0Можно узнать способ получения указателя с адресом 0x0?Можно! Открой заголовочные файлы гнуса и узри в них:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
#if defined(__GNUG__) && __GNUG__ >= 3
#define NULL __null
#else   /* G++ */
#ifndef __cplusplus
#define NULL ((void *)0)
#else   /* C++ */
#ifndef _WIN64
#define NULL 0
#else
#define NULL 0LL
#endif  /* W64 */



Но лично я предпочитаю что-то типа:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
    struct is
    {
    .
    .
    .
    public:

      template <class T>
      __INLINE
      static bool __fastcall Nil(register T* const ptr)
      {
#     if defined(__WIN32__) || defined(__WIN64__)
        return (0x00010000 > (size_t)ptr);
#     else
        return (0x0 == (size_t)ptr);
#     endif
      }
    .
    .
    .
    };
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624960
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_dev
Код: plaintext
1.
struct __Get;


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.
__mingw_ovr
__attribute__((__format__ (gnu_printf, 1, 2))) __MINGW_ATTRIB_NONNULL(1)
int printf (const char *__format, ...)
{
  register int __retval;
  __builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format );
  __retval = __mingw_vfprintf( stdout, __format, __local_argv );
  __builtin_va_end( __local_argv );
  return __retval;
}
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624967
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Можно узнать способ получения указателя с адресом 0x0?Можно! Открой заголовочные файлы гнуса и узри в них:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
#if defined(__GNUG__) && __GNUG__ >= 3
#define NULL __null
#else   /* G++ */
#ifndef __cplusplus
#define NULL ((void *)0)
#else   /* C++ */
#ifndef _WIN64
#define NULL 0
#else
#define NULL 0LL
#endif  /* W64 */

Ну и в какой конкретно строчке получается указатель с адресом 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.
    struct is
    {
    .
    .
    .
    public:

      template <class T>
      __INLINE
      static bool __fastcall Nil(register T* const ptr)
      {
#     if defined(__WIN32__) || defined(__WIN64__)
        return (0x00010000 > (size_t)ptr);
#     else
        return (0x0 == (size_t)ptr);
#     endif
      }
    .
    .
    .
    };

А тут?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624970
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devТы найдешь пренебрежение этой рекомендацией даже в исходниках RHEL, не говоря уже о заголовочных файлах реализации cstdlib.
1. Стандарт резервирует идентификаторы определённого вида для реализации.
2. Реализация (в данном случае — cstdlib) использует идентификаторы данного вида.

Как ты в следовании этой рекомендации смог увидеть пренебрежение ею?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624985
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestНу и в какой конкретно строчке получается указатель с адресом 0x0, но при этом не нулевой указатель?Поясняю для непонятливых - адреса с 0x0 по 0x0000FFFF в ОС Windows для x86 являются инвалидными только благодаря самой реализации ОС, в которой при доступе по этим адресам возникает исключение page fault, но это не значит, что эти адреса инвалидны в реализациях любых ОС, в т.ч. проприетарных или в реализациях прошивок контроллеров, которые могут хранить по этим адресам некие заранее известные структуры данных по заранее известным смещениям. Поэтому, валидно любое приведение любых адресов в арифметике указателей, чтобы там не насочиняли стандартописатели.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624989
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devвалидно любое приведение любых адресов в арифметике указателейМожно цитаты из стандарта?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625003
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devвалидно любое приведение любых адресов в арифметике указателейМожно цитаты из стандарта?Цитаты из стандарта о том, что для процессоров и контроллеров валидны все доступные им адреса памяти?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625007
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625012
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devЦитаты из стандарта о том, что для процессоров и контроллеров валидны все доступные им адреса памяти?
То что адрес 0 это такой же адрес для процессора как и другие не противоречит тому что в С++ обращение по этому адресу - UB.
Из С++ обращаться к нему нельзя, а из ассемблера например можно.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625016
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskya guestВ какой версии драфта пункт 8.3.2.5?
n4594, 8.3.2 параграф 5Хм. Но ведь это не Anatoly Moskovskyразыменование нулевого указателя упоминается как пример UB.Там написано что UB это инициализация ссылки выражением `*p` если `p == nullptr` (ну или вообще инициализация не валидным указателем на объект).
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625018
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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, а именно неинициализированный указатель.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625019
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
a guestинициализация не валидным указателем на объектинициализация выражением, которое не обозначает валидный объект.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625025
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devМожно! Открой заголовочные файлы гнуса и узри в них
Внутри кода стандартной библиотеки могут быть какие угодно хаки, не всегда даже являющиеся С++.
Так что не стоит оттуда брать примеры ))
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625026
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guesta guestинициализация не валидным указателем на объектинициализация выражением, которое не обозначает валидный объект.А какая разница? Представь, что ты пишешь на Си часть прошивки к контроллеру, а до тебя разработчики, что писали, к примеру boot loader на ассемблере, поместили в начальные адреса адресного пространства некие статичные инициализированные в бутстрапе структуры данных. Зная о формате этих структур, ты как к ним будешь доступ получать?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625029
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyВнутри кода стандартной библиотеки могут быть какие угодно хаки, не всегда даже являющиеся С++.
Так что не стоит оттуда брать примеры ))Без "грязных хаков" на Си/С++ системные вещи вообще не пишутся! Есть идеалисты, придумывающие стандарт, которому рекомендовано следовать, а есть программисты, которые вынуждены обходить ограничения стандартов.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625039
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devНет! В стандарте не сказано, что null указатель, это тоже самое, что (void*)0
Нет конечно, там сказано что (void*)0 дает null указатель. То, с чем вы пытаетесь спорить.
rdb_devИменно по этой причине в стандарт введен null указатель, который совсем не (void*)0, а именно неинициализированный указатель.
Ггггг.
Нет. Основная причина это корректные перегрузки функций.
Со старым NULL:
Код: plaintext
1.
2.
3.
void f(char*);
void f(int);
f(NULL); // ошибка: не понятно что вызывать (обе функции могут быть вызваны), хотя в большинстве случаев имеется в виду вызов f(char*)


С nullptr:
Код: plaintext
1.
2.
3.
void f(char*);
void f(int);
f(nullptr); // вызывается f(char*), как и задумывалось
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625073
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625077
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky[/src]
С nullptr:
Код: plaintext
1.
2.
3.
void f(char*);
void f(int);
f(nullptr); // вызывается f(char*), как и задумывалось

Еще не могу понять, каким образом компилятор C++ должен "дедуктировать", что тип std::nullptr_t , подходит для вызова функции void f(char*)?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625115
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devНикак не могу разглядеть - в каком месте тут UB?Да никто и не говорил, что UB из-за каста нуля к указателю.
Ты, похоже, вообще не понимаешь, что тебе пишут.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39625145
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_devНикак не могу разглядеть
rdb_devЕще не могу понять
Похоже нет смысла продолжать. ))
...
Рейтинг: 0 / 0
25 сообщений из 143, страница 4 из 6
Форумы / C++ [игнор отключен] [закрыт для гостей] / Пятничная шабонная магия
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]