Использование rvalues с оператором

#c #literals #rvalue #lvalue

#c #литералы #rvalue #lvalue

Вопрос:

Я изо всех сил пытался понять приведенный ниже код C:

 struct s {
        char m1;
        char m2;
};

int  main()
{
    /* This will print 1 */
    printf("%dn", amp;((struct s*)0)->m2);

}
 

Приведенная ниже часть, похоже, ведет себя немного запутанно при небольших изменениях:

 amp;((struct s*)0)->m2
 

При компиляции и запуске исходного кода я получаю ответ 1, который я ожидаю получить.

Я изменяю код, заменяя amp;((struct s*)0)->m2 на amp;((struct s*)0) , а затем получаю сообщение об ошибке: «значение lvalue требуется как унарный операнд ‘amp;'».

ВОПРОС: В исходной части кода, amp;((struct s*)0)->m2 , не был аргументом для amp; rvalue ? Если да, то почему тогда он достиг успеха компиляции, но не в случае модификации amp;((struct s*)0) ?

Ответ №1:

В этом случае:

  amp;((struct s*)0)
 

Операнд to amp; является результатом приведения, которое всегда является значением rvalue . В то время как в этом случае:

 amp;((struct s*)0)->m2
 

Операнд to amp; является результатом -> оператора, который является значением lvalue, в частности, именованным полем. Также обратите внимание, что это выражение приводит к неопределенному поведению, поскольку значение нулевого указателя разыменовывается с помощью -> оператора.