Подтвердить что ты не робот

Преобразует bool (false) в указатель, законный в С++?

Недавно я наткнулся на что-то странное: преобразование логического в указатель работает в Visual Studio 2013 и 2015, но не в GCC или Clang (в 3.5).

#include <iostream>

using namespace std;

void foo(int *ptr)
{
    std::cout << "foo";
}

int main()
{
   foo(false);
}

Ошибка GCC:

    main.cpp: In function 'int main()':
    main.cpp:13:13: error: cannot convert 'bool' to 'int*' for argument '1' to 'void foo(int*)'
    foo(false);
             ^

Я предполагаю, что false преобразуется в 0, что эквивалентно NULL. Замена вызова foo на foo(true) приводит к сбою компиляции с каждым компилятором.

Итак, мой вопрос: должен ли этот код компилироваться? Я не вижу преимущества преобразования false в указатель, мне кажется, что это будет только причиной ошибок после неправильного использования/рефакторинга и т.д.

4b9b3361

Ответ 1

Это не должно приниматься с С++ 11.

Смотрите Преобразования указателей (выделено мной):

Константа нулевого указателя (см. NULL) может быть преобразована в любой тип указателя, а результатом является значение нулевого указателя этого типа. Такое преобразование (известное как преобразование нулевого указателя) разрешено преобразовывать в cv-квалифицированный тип как одно преобразование, то есть оно не считается комбинацией числовых и квалификационных преобразований.

Примечание, поскольку С++ 11 a константа нулевого указателя может быть целым литералом со значением 0 (или prvalue типа std::nullptr_t), а false - нет, это логический литерал.

И до тех пор, пока константа нулевого указателя С++ 11 не будет определена как целочисленное постоянное выражение rvalue целочисленного типа, которое будет равно нулю, а false - это хорошо. (GCC будет предупреждать об этом.)

Из стандарта $4.10/1 Pointer conversions [conv.ptr] (акцент мой)

Константа нулевого указателя целочисленный литерал (2.13.2) со значением 0 или значением prdue типа std:: nullptr_t.

Преобразование константы нулевого указателя в указатель на cv-квалификацию тип одно преобразование, а не последовательность указателя преобразование, за которым следует квалификационное преобразование (4.4).