2015-06-18 6 views
0
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 = &123;' дает ту же ошибку. Вы заинтересованы в том, как и как в спецификации, или вы (думаете, что вам) нужна эта информация для чего-то? – usr2564301

ответ

7

Why can't I use &&a

Поскольку & дает адрес varibale и &a не является переменной.

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

6.5.3.2 Address and indirection operators

Constraints

1 The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.

[...]

Semantics

3 The unary & operator yields the address of its operand. [...]

Чтобы обойти это «ограничение» можно было бы ввести временное хранение с использованием соединения буквального, как это (предполагая, что 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 */ 
+0

Является ли '{& a}' инициализацией массива? –

+0

@JinKwon: Это инициализатор сложного литерала типа 'int *': https://en.wikipedia.org/wiki/C_syntax#Compound_literals – alk

2

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

+0

Правильно. Я ожидал двойной указатель.Адрес ('& (v)') адреса ('v = & (x)') –

+0

Адрес - это всего лишь один идентификатор, у которого больше нет адреса. Переменная имеет адрес, который указывает, где он сохраняется на ram или swap или что-то еще. – Iwan1993

5

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

3

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

Таким образом, в течение первых двух ошибок:

error: lvalue required as unary ‘&’ operand

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

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

error: label ‘a’ used but not defined

связан с тем, что из-за два && он лечащий a в качестве метки (см alk's answer).

Дело вы хотели бы добиться (получить адрес адреса) не представляется возможным, потому что не может получить адрес «постоянное значение», так как &a уже значение, но только адрес переменных ,

+0

Ваш комментарий к последней ошибке (по крайней мере) вводит в заблуждение. См. Мой обновленный ответ на это. – alk

+0

@alk Ты прав, не знал, о чем я думал. – moffeltje