Использование всего, кроме литерала 0
для сравнения с std::strong_ordering
- явное неопределенное поведение, см. [cmp.categories.pre] / 3 черновика C ++ 20.
Компилятор / стандартная библиотека решает, как или нужно ли это применять / диагностировать.
Один из способов достижения диагноза c для UB без какого-либо магического компилятора c - использовать std::nullptr_t
в качестве аргумента для перегруженного оператора сравнения std::strong_ordering
(который имеет неопределенный тип в соответствии со стандартом). Любой интеграл с нулевым литералом может быть неявно преобразован в std::nullptr_t
, но литералы с другими значениями или константными выражениями, которые не являются литералами, не могут. См. [conv.ptr] / 1 .
Это также упоминается в черновике как возможность.
В Libc ++ вместо этого используется указатель на некоторый скрытый класс. смотрите здесь .
Libstdc ++, похоже, делает нечто подобное, используя скрытый тип класса, который должен быть создан из указателя на себя, смотрите здесь .
Однако ни одна из этих реализаций не диагностирует все аргументы, которые приводят к UB согласно стандарту. В частности, все они также принимают nullptr
в качестве аргумента без диагноза c: https://godbolt.org/z/esnvqR
Я полагаю, что для полной диагностики всех случаев потребуется некоторый магический компилятор c.