Здесь есть небольшая проблема: это проблема оценки.
Обычно разыменование нулевого указателя равно Неопределенное поведение ;однако есть угловой случай (по крайней мере для gcc), который вызывает typeid(*p)
, где p
является нулем, является допустимым выражением.
Поэтому проблема здесь заключается в вашем уровне косвенности:
int* p = 0;
getname(*p); // p is null, *p invokes undefined behavior
typeid(*p).name(); // p is null, but it's probably okay in `typeid`
// because it's an unevaluated operand here
Для тех, кто интересуется углубленным изучением, выражение typeid
подробно описано в §5.2.8 (C ++ 11).
2 / Когда typeid
применяется к выражению glvalue, тип которого является полиморфным типом класса (10.3), результат ссылается на объект std::type_info
, представляющий тип самого производного объекта (1.8)(то есть динамический тип), к которому относится glvalue.Если выражение glvalue получено путем применения к указателю унарного оператора *
, а указатель является нулевым значением указателя (4.10), выражение typeid
выдает исключение std::bad_typeid
(18.7.3).
Хорошо, поэтому typeid(*p)
определяется, если p
указывает на полиморфный класс ... и в этом случае он выдает.
3 / Когдаtypeid
применяется к выражению, отличному от glvalue типа полиморфного класса, результат относится к объекту std::type_info
, представляющему статический тип выражения.Преобразования Lvalue-to-rvalue (4.1), массив-указатель (4.2) и функция-указатель (4.3) не применяются к выражению.Если тип выражения является типом класса, класс должен быть полностью определен.Выражение является неоцененным операндом (раздел 5).
Интересно, что нет упоминания нулевых указателей для неполиморфных классов.Я подозреваю, что неоцененный операнд это то, что позволяет это, но еще не нашел цитату.
6 / Если заголовок <typeinfo>
(18.7.1) не включено до использования typeid
, программа неработоспособна.
Диагностика не требуется.По крайней мере, на gcc, я думаю, что оно выдает предупреждение.