LINUX.ORG.RU

Насколько я помню, стандарт предписывает, что адресная арифметика на void * запрещена. Если компилятор это разрешает, то это расширение, которое работает с void * как с unsigned char *.

6.2.5 Types

1.  ... Types are partitioned into object types (types that fully describe
objects), function types (types that describe functions), and incomplete
types (types that describe objects but lack information needed to determine
their sizes).

19.  The void type comprises an empty set of values; it is an incomplete type
that cannot be completed.

6.5.6 Additive operators

2.  For addition, either both operands shall have arithmetic type, or one
operand shall be a pointer to an object type and the other shall have integer
type. (Incrementing is equivalent to adding 1.)
xaizek ★★★★★
()
Последнее исправление: xaizek (всего исправлений: 2)

Мой компилятор показывает 1, но будет ли так всегда?

Нет :-) Твой компилятор показывает sizeof (char) :-) И это согласно 6.2.4/26:

A pointer to void shall have the same representation and alignment requirements as a

pointer to a character type. Лол :-)

anonymous
()
Ответ на: комментарий от Sorcerer

Это согласно GCC'шному расширению, не стандарту.

Это согласно стандарту :-) Стандарт называется ISO/IEC 9899:1999 (E) :-) Пункт 6.2.5/26 :-)

anonymous
()
Ответ на: комментарий от anonymous

Там только про представление указателя, но не про арифметику с ним. Прочитай ещё раз. Смысл требования — в том, чтобы можно было void * прозрачно преобразовывать в указатели на другие типы.

i-rinat ★★★★★
()

void* - это указатель. и размер у него соответствует размеру указателя на твоей архитектуре. как у тебя там получилась единица - непонятно. GCC выдаёт 8, потому что у меня 64-битная машина. «размер» самого void не имеет никакого смысла для программиста. это нужно для компилятора и только.

выше i-rinat всё подробно расписал. там нет никакой дуальности. вся адресная арифметика работает, как обычно.

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 1)

Парни, парни, под смещением я подразумевал не offset, а shift, если вы об этом. Т.е.

void* p = ... ;
++p;
p += 1;
p += 2;
//И т.п.

normann ★★★
() автор топика
Ответ на: комментарий от anonymous

Это согласно стандарту :-) Стандарт называется ISO/IEC 9899:1999 (E) :-) Пункт 6.2.5/26 :-)

Аноним-улыбан, а не подскажете, почему gcc ругается на эту программу, если собирать с -Wall -Wpedantic -std=c99 ?

int main(void)
{
   void *v = 0;
   
   return (v + 1 == 0);
}

См. также, почему арифметика с void * - это фича GCC: https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html#Pointer-Arith

Также посмотрите в стандарт C11, там кое-что уточнено, чтобы не вводить вас в заблуждение:

6.5.6 Additive operators

For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to a complete object type and the other shall have integer type. (Incrementing is equivalent to adding 1.)

А ваш 6.2.5/26 тут не при делах. Кстати, к этому пункту в стандарте есть сноска специально для вас, - там объясняется, для чего он нужен.

Sorcerer ★★★★★
()
Ответ на: комментарий от normann

Парни, парни, под смещением я подразумевал не offset, а shift, если вы об этом.

Я про это и говорил, это анонимный эксперт не понимает.

Gargamel
()

Мой компилятор показывает 1, но будет ли так всегда?

Нет. gcc даже честно предупреждает, что арифметика над void* — это его фишка.

kawaii_neko ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.