2014-01-07 2 views
5

Я собирал программу на C с помощью gcc 4.7.2. Я суммирую адрес, который является типом void * с некоторым смещением. (void * + size) должен дать предупреждение. Если это не то, сколько байтов будет добавлено, если размер равен 1 &, если размер равен 50. Мое единственное беспокойство в этом случае должно быть предупреждением о том, что мы добавляем что-то к указателю пустоты?Должен ли компилятор предупреждать о арифметике указателя с указателем void?

12   int size = 50; 
/*Allocate a block of memory*/ 
14   void *BlockAddress = malloc(200); 
15   if(!BlockAddress) 
16     return -1; 
17   address1    = (int *)BlockAddress; 
18   address2    = BlockAddress + 1*size; 
19   address3    = BlockAddress + 2*size; 

Благодаря

+0

Вы можете проверить, но я думаю, что это добавит 4 байта (размер указателя), если он работает. Если вы не укажете тип, компилятор не сможет узнать, сколько байтов добавить. Например. для char 1 байт добавляется, для int pointer добавляется 4 байта и так далее. Итак, я думаю, что значением по умолчанию будет размер указателя, который равен 4 байтам. –

+0

Да, я уже проверил его. И я думал так же, как вы думаете, если я не скомпилировал его и не запустил, эта программа скомпилирована без ошибок или предупреждений. И он добавляет 1 не 4, вот почему задал вопрос, почему это так. – Javed

ответ

9

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

С С Standard

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

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

GNU C позволяет использовать вышеуказанное, учитывая размер void is 1.

От 6.23 Arithmetic on void- and Function-Pointers:

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

Так происходит по выше линии мы получаем:

address2    = BlockAddress + 1*size; //increase by 50 Bytes 
address3    = BlockAddress + 2*size; //increase by 100 Bytes 
+1

'gcc' говорит' предупреждение: указатель типа 'void *', используемый в арифметике 'на этом. – usr2564301

+0

@Jongware - см. Мои правки. – Sadique

+0

Спасибо Acme, по крайней мере, это имеет смысл, поскольку вы сказали: «GNU C позволяет вышесказанное, учитывая, что размер void равен 1», теперь размер void является одним звуком ужасным? не так ли ? – Javed

0

Это вполне допустимо. Пустота * содержит адрес, а добавление - просто указывает на следующий байт в памяти. Ничего не беспокоиться о здесь ...

+1

за исключением того, что вы не можете сделать BlockAddress + 1 ... – Rob

+0

Спасибо It'sPate, но не думайте, что если взять int ptr, то он будет увеличиваться с 4 байтами и удваивать с 8 байтами, пока указатель char с 1 байтом, так что что для пустоты? то есть 1. Вот почему не потому, что он переходит на следующую позицию. – Javed

8

Арифметика указателей с void * является GCC extension и не стандартный C.

Лучше не делать такие вещи. Используйте либо char * BlockAddress = malloc(200);, либо лийте его для address2 и address3.

+1

Зачем им придумывать такое бездумное расширение? Это безумие. – Rob

+0

Спасибо, я знаю, что у меня есть тип приведения для правильной работы, скажем случайно, что я забыл привести к типу, чтобы он дал мне предупреждение или более правильно, он должен дать мне ошибку? – Javed

+0

Это зависит от уровня предупреждения и параметров, которые вы указали. – glglgl

Смежные вопросы