Информация об изменениях

Сообщение Re[11]: так компайл тайм рефлекшину быть 26-й стандарт ?? от 25.03.2026 7:35

Изменено 25.03.2026 7:39 ботаныч

Re[11]: так компайл тайм рефлекшину быть 26-й стандарт ??
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, ботаныч, Вы писали:


Б>>Здравствуйте, rg45, Вы писали:


Б>>привет.

R>Хорошо, "то же самое" зачёркриваем. Оставляем только: "через оператор доступа к членам (точку) можно доступаться не только к инстансным, но и к статическим членам". Это было главной мыслью, которую я высказал для полноты картины использования этих двух операторов.
Да я вообще хотел обойти пока сторой вопрос со статикой отмазавшись фразой

Чего аж вообще не скажешь за оператор точка, который без инстанса (за некоторыми исключениями) рантайма неупотребим.


Б>>более близко выглядело бы ((std::numeric_limits<double>*)nullptr)->epsilon(), для статики.



R>Во-первых, это уже другой оператор (->), о котором и речи не шло изначально.

ближе, т.е. без создания инстанса (объекта)

R>Во-вторых, здесь тоже будет создан "инстанс", т.к. указатель — это тоже объект (нулевой указатель в т.ч).

разыменования здесь нет. здесь приведение nullptr к типу, в котором реализован статический метод.

R>Выигрыш по сравнению с созданием объекта пустой структуры сомнителен. В-третьих, я вот думаю, а не будет ли здесь UB (разыменовывание нулевого указателя)? Вот это не очень очевидно для меня — с одной стороны, разыменовывание налицо, с другой — доступа к области памяти, занимаемой объектом нет, this не используется даже формально.

собственно

В выражении ((std::numeric_limits<double>*)nullptr)->epsilon() никакой объект не будет инстанцирован.
Это происходит по следующим причинам:
Статическая природа: Функция epsilon() определена как static constexpr. В языке C++ вызов статического метода через указатель — это лишь синтаксический способ указать компилятору на конкретный тип. Разыменования указателя в реальности не происходит.
Работа компилятора: Для вызова этой функции компилятору достаточно знать тип (std::numeric_limits). Он подставляет значение константы прямо в место вызова еще на этапе компиляции.
Отсутствие UB: Так как фактического обращения к памяти по адресу nullptr не случается, это выражение безопасно и не вызывает неопределенного поведения.

для перехода в точку можно было бы написать (*(std::numeric_limits<double>*)nullptr).epsilon(), но тут уже UB, потому я написал самое близкое и корректное к std::numeric_limits<double>::epsilon().
Но самое забавное, что мы даже не это обсуждаем, мы обсуждаем совсем другую точку, которую предложил коллега B0FEE664.
А именно точка времени компиляции со некими скрытыми итерабильными свойствами времени компиляции. А это немного другой оператор.
Re[11]: так компайл тайм рефлекшину быть 26-й стандарт ??
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, ботаныч, Вы писали:


Б>>Здравствуйте, rg45, Вы писали:


Б>>привет.

R>Хорошо, "то же самое" зачёркриваем. Оставляем только: "через оператор доступа к членам (точку) можно доступаться не только к инстансным, но и к статическим членам". Это было главной мыслью, которую я высказал для полноты картины использования этих двух операторов.
Да я вообще хотел обойти пока стороной вопрос со статикой отмазавшись фразой

Чего аж вообще не скажешь за оператор точка, который без инстанса (за некоторыми исключениями) рантайма неупотребим.

в некоторые исключение как раз входила статика, constexpr, constval выражения в контексте decltype или sizeof(obj.field)

Б>>более близко выглядело бы ((std::numeric_limits<double>*)nullptr)->epsilon(), для статики.



R>Во-первых, это уже другой оператор (->), о котором и речи не шло изначально.

ближе, т.е. без создания инстанса (объекта)

R>Во-вторых, здесь тоже будет создан "инстанс", т.к. указатель — это тоже объект (нулевой указатель в т.ч).

разыменования здесь нет. здесь приведение nullptr к типу, в котором реализован статический метод.

R>Выигрыш по сравнению с созданием объекта пустой структуры сомнителен. В-третьих, я вот думаю, а не будет ли здесь UB (разыменовывание нулевого указателя)? Вот это не очень очевидно для меня — с одной стороны, разыменовывание налицо, с другой — доступа к области памяти, занимаемой объектом нет, this не используется даже формально.

собственно

В выражении ((std::numeric_limits<double>*)nullptr)->epsilon() никакой объект не будет инстанцирован.
Это происходит по следующим причинам:
Статическая природа: Функция epsilon() определена как static constexpr. В языке C++ вызов статического метода через указатель — это лишь синтаксический способ указать компилятору на конкретный тип. Разыменования указателя в реальности не происходит.
Работа компилятора: Для вызова этой функции компилятору достаточно знать тип (std::numeric_limits). Он подставляет значение константы прямо в место вызова еще на этапе компиляции.
Отсутствие UB: Так как фактического обращения к памяти по адресу nullptr не случается, это выражение безопасно и не вызывает неопределенного поведения.

для перехода в точку можно было бы написать (*(std::numeric_limits<double>*)nullptr).epsilon(), но тут уже UB, потому я написал самое близкое и корректное к std::numeric_limits<double>::epsilon().
Но самое забавное, что мы даже не это обсуждаем, мы обсуждаем совсем другую точку, которую предложил коллега B0FEE664.
А именно точка времени компиляции со некими скрытыми итерабильными свойствами времени компиляции. А это немного другой оператор.