Таблица thumbnail_kvstore не существует

Окончательный вывод: арифметика на void* является незаконной как в C, так и в C ++.

GCC разрешает ее как расширение, см. Арифметика на void - и указатели функций (обратите внимание, что этот раздел является частью главы «C Расширения» руководства). Clang и ICC, вероятно, разрешают арифметику void* для совместимости с GCC. Другие компиляторы (такие как MSVC) отклоняют арифметику на void*, а GCC запрещает ее, если указан флаг -pedantic-errors, или если указан флаг -Werror-pointer-arith (этот флаг полезен, если ваша база кода также должна компилироваться с помощью MSVC ).

C Standard Speaks

Котировки берутся из черновика n1256.

Стандартное описание состояний операции добавления:

6.5.6-2: Для добавления оба операнда должны иметь арифметический тип, или один операнд должен быть указателем на тип объекта, а другой должен иметь целочисленный тип.

blockquote>

Итак, вопрос в том, является ли void* указателем на «тип объекта» или, что то же самое, является ли void «типом объекта». Определение для «типа объекта»:

6.2.5.1: Типы разделены на типы объектов (типы, которые полностью описывают объекты), типы функций (типы, описывающие функции) и неполные типы (типы, которые описывают объекты, но не имеют информации, необходимой для определения их размеров).

blockquote>

И стандарт определяет void as:

6.2.5-19: Тип void содержит пустой набор значений; это неполный тип, который не может быть завершен.

blockquote>

Поскольку void является неполным, он не является типом объекта. Поэтому он не является допустимым операндом операции сложения.

Поэтому вы не можете выполнить арифметику указателя на указателе void.

Примечания

Первоначально он считалось, что арифметика void* разрешена из-за этих разделов стандарта C:

6.2.5-27: указатель на void должен иметь те же требования к представлению и выравниванию, что и указатель для символьного типа.

blockquote>

Однако

Те же требования к представлению и выравниванию подразумевают взаимозаменяемость в качестве аргументов функций, возврат значений из функций и члены союзов.

blockquote>

Итак, это означает, что printf("%s", x) имеет то же значение, что x имеет тип char* или void*, но это не означает, что вы можете сделать арифметику на void*.

Примечание редактора: этот ответ был отредактирован, чтобы отразить окончательный вывод.

20
задан DhiaTN 15 December 2016 в 00:49
поделиться