#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, в частности, именованным полем. Также обратите внимание, что это выражение приводит к неопределенному поведению, поскольку значение нулевого указателя разыменовывается с помощью ->
оператора.