Почему я не могу использовать `&&a` в C?

int main(int argc, char * argv[]) {
  int       a = 10;
  int *    sp = &a;
  int * * dp1 = &sp;
  int * * dp2 = &&a;           // NG
  int * * dp3 = &(&a);         // NG
  int * * dp4 = &((int *) &a); // NG
}
$ cc test.c
test.c: In function ‘main’:
test.c:6:17: error: lvalue required as unary ‘&’ operand
   int * * dp3 = &(&a);         // NG
                 ^
test.c:7:17: error: lvalue required as unary ‘&’ operand
   int * * dp4 = &((int *) &a); // NG
                 ^
test.c:5:3: error: label ‘a’ used but not defined
   int * * dp2 = &&a;           // NG
   ^

4 ответа

Решение

Почему я не могу использовать &&a

Так как & дает вам адрес варибале и &a не является переменной

Проект C 11 определяет следующее:

6.5.3.2 Операторы адреса и косвенности

Ограничения

1 Операндом унарного оператора & должен быть либо указатель функции, результат оператора [] или унарного *, либо значение l, которое обозначает объект, который не является битовым полем и не объявлен с классом хранения регистра. спецификатор.

[...]

Семантика

3 Унарный оператор & выдает адрес своего операнда. [...]

Чтобы обойти это "ограничение", можно ввести временное хранилище, используя составной литерал, подобный этому (при условии, по крайней мере, C99):

int a = 42; 
int ** ppa = &((int *){&a});

В качестве примечания со ссылкой на сообщение об ошибке ниже:

test.c:5:3: error: label ‘a’ used but not defined
   int * * dp2 = &&a;           // NG
   ^

gcc (и, возможно, другие) определяют расширение стандарта C, позволяющее использовать && оператор на одном операнте, если оперант идентифицирует метку. (Подробнее об этом здесь: https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html)

Пример:

void * pv = &&lbl;

goto *pv;

/* some dead code  */

lbl:;

/* living code again here */

Потому что вы можете получить только адрес переменной, а не адрес значения (заданного &&) и, кроме того, && является логическим И как говорит @UnWind.

В каждом утверждении эта часть: &a рассматривается как числовое значение (потому что он получает адрес переменной).

Итак, для первых двух ошибок:

ошибка: lvalue требуется как унарный операнд '&'

Первый & трактуется как побитовый оператор AND и поэтому ожидает, что перед ним будет значение. (т.е. 2 & 3).

Для последней ошибки:

ошибка: метка "а" используется, но не определена

Это связано с тем, что из-за двух && это лечит a как ярлык (см . ответ алка).

То, чего вы хотели бы достичь (получить адрес по адресу), невозможно, потому что не может получить адрес с "постоянным значением", так как &a это уже значение, но только адрес переменных.

&var дает вам адрес вашей переменной, поэтому я бы не знал, что вы ожидаете &&var быть адресом адреса? Поправь меня, если я ошибаюсь.

Другие вопросы по тегам