Просматривая материалы конференции Становимся родным, 2012 г.
(который я настоятельно рекомендую посмотреть всем программистам на C++), я обратил внимание на один пример кода:
Можете ли вы, не подглядывая в ответ, сказать, что эта программа напечатает и, самое главное, Почему ? Под катом — предположение разработчика Кланг от Google о том, почему этот код работает именно так.#include <iostream> struct S { int n; }; struct X { X(int) {} }; void f(void*) { std::cerr << "Pointer!\n"; } void f(X) { std::cerr << "X! \n"; } int main() { f(S().
n); }
Еще раз для тех, кто не уловил: разработчик компилятора Google C++ не знает этого наверняка, у него есть только предположение.
Отвечать
При компиляции в соответствии со стандартом C++98 этот код выведет " ИКС! ", при компиляции в соответствии со стандартом C++11 этот код выведет " Указатель! ".
# clang++ -std=c++98 -g -o cxx11-4 cxx11-4.cpp
# .
/cxx11-4 X! # clang++ -std=c++11 -g -o cxx11-4 cxx11-4.cpp # .
/cxx11-4
Pointer!
Вопрос к разработчикам стандарта C++11.
Пояснения
Давайте внимательно посмотрим на строку f(S().
n);
Как видите, здесь создается экземпляр структуры S. У него нет явного конструктора, что означает вызов конструктора по умолчанию.
И здесь на сцену выходит стандарт C++11 с расширенной поддержкой константных выражений ( Обобщенные константные выражения ).
Любую функцию (включая конструктор) в C++11 можно объявить так, чтобы она всегда возвращала одно и то же выражение.
Это сделано для того, чтобы можно было писать такой код: int get_five() {return 5;}
int some_value[get_five() + 7];
Константные выражения используются в объявлениях массивов, перечислениях и блоках switch\case. И компилятор C++11 пытается считать константной любую функцию, которая может быть константой, чтобы иметь возможность использовать ее во всех этих местах.
А как насчет конструктора структуры? С ? Хорошо, если он присвоит переменной н всегда какое-то конкретное число (и стандарт этого не запрещает) — а значит, это может быть и константное выражение.
Зачем ему это назначать? н каждый раз разные значения? Присваивает ноль.
Почему именно ноль? Есть ли у вас в голове какой-нибудь более умный смысл?
Итак, приведенная выше строка эквивалентна: f(0);
Ну, это, как мы знаем, полностью эквивалентно: f(NULL);
И это скорее превратится в пустота* чем структура X (даже с соответствующим конструктором Х(целое) ).
И теперь у нас есть явная задача недействителен f(недействителен*) ! Ну, это напечатано» Указатель! ".
Почему этого не происходит в компиляторе, поддерживающем C++98? Да, потому что в нем нет этой самой продвинутой поддержки константных выражений.
Конструктор структуры по умолчанию С нет оснований для присвоения собственности н значение равно нулю (стандарт этого не требует).
Ну, он этого не делает. Что означает линию е(S().
n); не может быть однозначно преобразовано в е(0); со всеми вытекающими последствиями.
Заключение
Стандарт C++11 новый, его поддержка в компиляторах тоже пока сырая.Будьте готовы к таким сюрпризам.
Теги: #c++11 #C++ #драконы #C++
-
В Вашей Системе Обнаружены Опасные Трояны
19 Oct, 24 -
Вакансия На Радио-Ю 22 Декабря.
19 Oct, 24 -
Сразу В Appstore
19 Oct, 24