2013-12-19 3 views
2

я играл с недействительными указателями и создал этот пример:GCC 2.9 и «именующий требуется в качестве левого операнда назначения»

#include <stdio.h> 

struct intint { 
    int a; 
    int b; 
}; 

struct intshortshort { 
    int a; 
    short b; 
    short c; 
}; 

void fill_me(struct intint **pii, void *piss) 
{ 
    (void*)*pii = piss;    // Question about this line? 
} 

int main() 
{ 
    struct intint *pii = NULL; 
    struct intshortshort iss; 
    iss.a = iss.b = iss.c = 13; 

    fill_me(&pii, &iss); 

    printf("%d..%d\n", pii->a, pii->b); 


    return 0; 
} 

Вопрос:

Когда я использую GCC версию 2.95. 4 все компилируется и работает, как ожидалось, но GCC версии 4.7.3 дает мне следующую ошибку:

void_pointer.c:16:17: error: lvalue required as left operand of assignment 

есть ли причина, почему добавление (недействительными *) в Lvalue не допускается больше?

Редактировать: Спасибо за ответы, я думаю, что понял проблему, но вопрос «почему это было в порядке?» по-прежнему интересен.

+2

результат броска не именующее, если это не в качестве ссылки. Например, http://coliru.stacked-crooked.com/a/61ba4d86f65eaa3e – chris

+0

@chris Нет, результат приведения не является периодом lvalue. Возможно, вы думаете о другом языке программирования. –

+0

@PascalCuoq, Простите меня, я подумал, что это было помечено C++, когда я сделал этот комментарий. Я почти уверен, что я просто сумасшедший. – chris

ответ

0

Вы не можете использовать оператор приведения на левый операнд оператора присваивания в С.

2

Он не работает по той же причине, почему

int x, y; 
    (int)x = y; 

не работает. Результат приведения не является «lvalue», он не содержит ячейки памяти, в которых вы можете хранить что-то внутри. Скорее рассмотрите результат (int)x как временную, невидимую переменную, которая существует только во время выполнения этой операции.

3

Этот вопрос не о void*, это о typecast и lvalue.

, например:

#include <stdio.h> 

int main() 
{ 
    int n; 
    (int)n = 100; 
    return 0; 
} 

Этот код вызывает ту же ошибку: Lvalue, необходимые в качестве левого операнда назначения.

Это потому, что оператор = требует, чтобы его левый операнд изменял значение-lvalue.

Итак, что же такое lvalue? и что такое modifiable-lvalue? См. wikipedia:Value.

0

Хитрость заключается в том, чтобы бросить в void** и затем разыменования это:

void fill_me(struct intint **pii, void*piss) 
{ 
     *(void **)pii=piss; 
} 

выход, как и ожидалось:

13..851981 

13 is obvious 
851,981 - 13 = 851,968 
851,968/(256*256) = 13 
there are the 2 shorts as an int 
+0

@GintsDev Это то, что вы пытались сделать? –

+0

Спасибо за ваш ответ, но я искал больше по той причине, что раньше версии gcc не имели ошибки. – GintsDev

+0

@GintsDev Не понятно, хотите ли вы что-то, что сработало, или хотели узнать, что изменилось, так или иначе это будет работать :) –

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