Пока просматривал исходный код Qt я наткнулся на этот драгоценный камень:Bizarre static_cast трюк?
template <class T> inline T qgraphicsitem_cast(const QGraphicsItem *item)
{
return int(static_cast<T>(0)->Type) == int(QGraphicsItem::Type)
|| (item && int(static_cast<T>(0)->Type) == item->type()) ? static_cast<T>(item) : 0;
}
Обратите внимание на static_cast<T>(0)->Type
? Я использую C++ в течение многих лет, но никогда не видел, чтобы 0 использовался в static_cast раньше. Что делает этот код и он безопасен?
фона: Если вы черпаете из QGraphicsItem
вы призваны объявить уникальное значение перечисления под названием Type
, что и реализовать виртуальную функцию, называемую type
, которая возвращает его, например:
class Item : public QGraphicsItem
{
public:
enum { Type = MAGIC_NUMBER };
int type() const { return Type; }
...
};
Вы можете сделать это:
QGraphicsItem* item = new Item;
...
Item* derivedItem = qgraphicsitem_cast<Item*>(item);
Это, вероятно, поможет объяснить, что пытается сделать static_cast.
Опять же, подтвердите свое утверждение, что это «технически неопределенное поведение». См .: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232 – p00ya
@ p00ya: Это дефект _active_. Его предлагаемая резолюция не была согласована и не была включена в предстоящий проект окончательного комитета C++ 0x. Направление с помощью нулевого указателя (или разыменование нулевого указателя - выбор) приводит к неопределенному поведению. –
Последнее, что я прочитал, было несколько тонкостей и дискуссий о том, является ли указатель разыменованным или нет (например, если '& * ((int *) 0)' не определено из-за кажущегося разыменования, даже если его можно было пропустить - или вызвать статическая функция-член через указатель нулевого экземпляра, что больше похоже на то, что происходит в вопросе). ИМО, юристы по языкам могут понять это, и мы, смертные, можем писать код, который не похож на него. Нулевые указатели нулей :) – AshleysBrain