Ответ 1
C говорит:
Два указателя сравнивают одинаковые, если и только если оба являются нулевыми указателями, оба являются указателями на тот же объект (включая указатель на объект и подобъект в начале) или функцию, оба являются указателями на один последний элемент одного и того же объекта массива, или один - указатель к одному концу конца одного объекта массива, а другой - указателю на начало другого объект массива, который происходит сразу же после первого объекта массива в адресе пространство.
С++ говорит:
Два указателя одного типа сравнивают одинаковые, если и только если оба они равны нулю, оба указывают на одну и ту же функцию или оба представляют один и тот же адрес.
Следовательно, это будет означать, что:
а)
полностью определено поведение в С++ (в соответствии со стандартом 03 или 11) для сравнения двух указателей void для (in) равенства, которые указывают на действительные, но разные объекты.
Итак, да, в C и С++. Вы можете сравнить их, и в этом случае они будут сравниваться как истинные, если они указывают на один и тот же объект. Это просто.
б)
сравнивает (== or! =) два значения типа void *, которые всегда определены, или требуется, чтобы они содержали указатель на допустимую область объекта/памяти?
Опять же, сравнение хорошо определено (стандарт говорит "если и только если", поэтому каждое сравнение двух указателей хорошо определено). Но потом...
- С++ говорит в терминах "адрес", поэтому я считаю, что это означает, что стандарт требует, чтобы это работало "как и следовало ожидать",
- C, однако, требует, чтобы указатели были либо нулевыми, либо указывали на объект или функцию, либо один элемент за объектом массива. Это, если мои навыки чтения не выключены, означает, что если на данной платформе у вас есть два указателя с одинаковым значением, но не указывая на действительный объект (например, несогласованный), их сравнение должно быть четко определенным и давать false.
Это удивительно!
Действительно, не работает 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 на самом деле не подчиняется стандарту, но дает более интуитивный результат.