Почему эта странная совместимость bool и указателей в C ++? - PullRequest
1 голос
/ 06 ноября 2010

Это не только допустимо и не выдает никаких предупреждений даже с -Wall:

void* p = false;  // actually 'true' doesn't work here
bool b = "Hello, Boolean!";

, но и это правило совместимости позволяет выбрать перегруженную функцию / оператор для неправильного типа.Допустим, вы перегрузили operator << для всех основных типов и забыли перегрузить указатель void, тогда компилятор может выбрать версию, которая принимает bool, или наоборот.

Так что же эточто делает это правило совместимости более важным, чем странные (и крайне нежелательные) побочные эффекты с перегруженными функциями?

(Правка: удалены все ссылки на C, они были неверны: правила преобразования в основном одинаковы в C.) * +1010 *

1 Ответ

7 голосов
/ 06 ноября 2010

Что вы подразумеваете под "C может справиться с этим правильно"?C не допускает перегрузки функций, поэтому вы гарантированно получите конвертацию указателя bool <->, на которую вы жалуетесь.

Вы спрашиваете, почему существует это преобразование?

Первое -на самом деле это не конверсионный указатель bool ->, а признание того, что литерал false означает 0, что является допустимым значением указателя.Вот почему он не работает с true, и он не работает с переменной bool.

Второе, потому что хорошо иметь возможность писать:

if (p)

вместо

if (p != 0)

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

РЕДАКТИРОВАТЬ: правила из стандарта, влияющие T* p = false;:

Константа нулевого указателя - это целочисленное значение константы выражения типа целочисленного типа, которое оценивается как ноль

и

Типы bool, char, char16_t, char32_t, wchar_t и подписанныйи целочисленные типы без знака вместе называются целочисленными типами.Синонимом целочисленного типа является целочисленный тип.

и

Логические литералы - это ключевые слова false и true.Такие литералы являются prvalues ​​и имеют тип bool.

...