C++11 обратная совместимость (преобразование нулевой целочисленной константы в указатель)
стандарт C++ позволяет неявное преобразование нуля целочисленную константу к указателю любого типа.
следующий код недопустим, так как значение v
не является постоянным здесь:
float* foo()
{
int v = 0;
return v; // Error
}
но следующий код является правильным:
float* foo()
{
const int v = 0;
return v; // Ok in C++98 mode, error in C++11 mode
}
вопрос почему gcc
и clang
(пробовал разные версии) скомпилируйте код правильно в режиме c++98/03, но верните предупреждение/ошибку при компиляции в режиме c++11/14 (-std=c++11
)? Я попытался найти изменения в рабочем проекте PDF на C++11, но безуспешно.
компиляторы Intel compiler 16.0 и VS2015 не показывают ошибок и предупреждений в обоих случаях.
1 ответов
GCC и Clang ведут себя по-разному с -std=c++11
поскольку C++11 изменил определение константы нулевого указателя, а затем C++14 изменил его снова, см. Core д-р 903, который изменил правила в C++14, так что только литералы null указатель константы.
в C++03 4.10 [conv.ПТР] сказал:
константа нулевого указателя-это интегральное выражение константы (5.19) rvalue целочисленного типа, которое вычисляется как ноль.
что позволяет всевозможные выражения, пока они постоянны и оцениваются до нуля. Перечисления,false
, (5 - 5)
etc. так далее. ... это вызывало множество проблем в коде C++03.
в C++11 говорится:
константа нулевого указателя-это интегральное выражение константы (5.19) prvalue целочисленного типа, которое вычисляется как ноль или prvalue типа
std::nullptr_t
.
и в C++14 он говорит:
константа нулевого указателя-это целочисленный литерал (2.14.2) со значением zero или prvalue типа
std::nullptr_t
.
это гораздо более ограничительное правило и имеет гораздо больше смысла.