C говорит:
Два указателя сравниваются равными, если и только если оба являются нулевыми указателями, оба являются указателями на один и тот же объект (включая указатель на объект и подобъект в его начале) илиобе функции являются указателями на один за последним элементом одного и того же объекта массива, или один - указатель на один за концом одного объекта массива, а другой - указатель на начало другого объекта массива, который следует сразу запервый объект массива в адресном пространстве.
C ++ говорит:
Два указателя одного типа сравниваются равными, если и только если они оба равны нулю, оба указывают наодна и та же функция или оба представляют один и тот же адрес.
Следовательно, это будет означать, что:
a)
это полностью определенное поведение в C ++(в соответствии со стандартом 03 или 11) сравнить два пустых указателя на (в) равенство, которые указывают на действительные, но разные объекты.
Так что да, как в C, так и в C ++.Вы можете сравнить их, и в этом случае они будут сравниваться как истинные, если они указывают на один и тот же объект.Это просто.
b)
сравнивает (== или! =) Два значения типа void *, которые всегда определены, или требуется, чтобы они содержали указатель на действительныйобласть объекта / памяти?
Опять же, сравнение четко определено (стандарт гласит «тогда и только тогда», поэтому каждое сравнение двух указателей четко определено).Но тогда ...
- C ++ говорит в терминах "адреса", поэтому я думаю, что это означает, что стандарт требует, чтобы это работало "как мы ожидали",
- Cоднако оба указателя должны быть либо нулевыми, либо указывать на объект или функцию, либо на один элемент после объекта массива.Это, если мои навыки чтения не выключены, означает, что если на данной платформе у вас есть два указателя с одинаковым значением, но не указывающих на действительный объект (например, смещенный), сравнение их должно быть четко определено и давать ложь.
Это удивительно!
На самом деле это не так, как работает GCC :
int main() {
void* a = (void*)1; // misaligned, can't point to a valid object
void* b = a;
printf((a == b) ? "equal" : "not equal");
return 0;
}
результат:
equal
Может быть, это UB в C иметь указатель, который не является нулевым указателем и не указывает на объект, подобъект или один за последним объектом в массиве?Хм ... Это было мое предположение, но у нас есть следующее:
Целое число может быть преобразовано в любой тип указателя.За исключением случаев, указанных ранее, результат определяется реализацией, может быть неправильно выровнен, может не указывать на объект ссылочного типа и может быть представлением прерываний.
Так что я могу интерпретировать толькоэто то, что вышеупомянутая программа четко определена, и стандарт C ожидает, что она напечатает «не равно», в то время как GCC на самом деле не подчиняется стандарту, но дает более интуитивный результат.