Если ++a возвращает lvalue, то почему &(++a) показывает ошибку компиляции?

Я слышал, что ++a возвращает l-значение в c, где a++ возвращает r-значение в c. Так как ++a возвращает l-значение, то почему &(++a) выдает ошибку компиляции?

Вот ссылка: Почему ++x является lvalue, а x++ - rvalue?< /а>

#include<stdio.h>

int main()
{
    int a=1,*p;
    p=&(++a);
    printf("%d",p);
}

Сообщение об ошибке:

guess.c: In function ‘main’:
guess.c:6:4: error: lvalue required as unary ‘&’ operand
  p=&(++a);

person Gaurav Katare    schedule 28.06.2019    source источник
comment
Вы ошибаетесь: ++a не возвращает lvalue в C, поэтому вы исходите из ложной предпосылки, что приводит к ложному заключению. Обратите внимание, что ваш связанный вопрос явно помечен c++ и c++11 — то, что применимо в C++, особенно в C++11 или более поздних версиях, очень часто не применимо к C, даже к C11 или C17 (C18 ).   -  person Jonathan Leffler    schedule 28.06.2019
comment
Как вы думаете, почему временное значение может быть lvalue?   -  person user6556709    schedule 28.06.2019
comment
@Bathsheba, это совсем бесполезно, потому что, если вы погуглите сообщение об ошибке вместе со словом «приращение», вы обнаружите, что это дубликат. Это, в сочетании с ложной предпосылкой без источников к ней, и не так уж много осталось для спасения.   -  person Antti Haapala    schedule 28.06.2019
comment
@Bathsheba, что наряду с сообщением об ошибке довольно явно указывается, что то, что дается &, на самом деле не является lvalue.   -  person Antti Haapala    schedule 28.06.2019
comment
@AnttiHaapala: молодец; вы зарекомендовали себя как более опытный, чем ОП.   -  person Bathsheba    schedule 28.06.2019


Ответы (1)


Вы путаете C с C++. В C++ вы действительно можете это сделать. В C ++a просто дает вам новое значение a (значение r в терминах C++), и вы не можете взять его адрес.

И, конечно же, ваш отпечаток должен быть printf("%d\n", *p);, а не printf("%d\n",p); (или printf("%p\n", (void *)p);, если вы хотите напечатать адрес a).

person Blaze    schedule 28.06.2019
comment
@EricPostpischil было бы бессмысленно определять ++a, возвращающее lvalue. Он возвращает временный. Даже в соглашении об именах C++ временное не может быть lvalue. - person user6556709; 28.06.2019
comment
@ user6556709: Это имело бы смысл. Производит ли он временный результат, не имеет значения. Стандарт C может сказать, что он создает (а не возвращает; это не вызов функции) lvalue, и нет никаких технических препятствий для реализации этого. Это просто не так. - person Eric Postpischil; 28.06.2019
comment
@EricPostpischil Не имеет значения, что результат является временным. Он определяет время его жизни. Если сделать его значением lvalue, это окажет интересное влияние на то, как обрабатывается время жизни. - person user6556709; 28.06.2019
comment
@user6556709 user6556709 Почему это может повлиять на время жизни, чтобы показать (потому что в C он не возвращает) фактическое увеличение элемента? С++ кажется вполне довольным? Я просто после подробностей? Хорошо, вы можете сказать, что C++ — это не C, но на самом деле это ничего не объясняет. - person Gem Taylor; 28.06.2019
comment
@ user6556709: Во-первых, вы ошибаетесь, что результат ++ является временным. Единственными временными объектами в C являются выражения, отличные от lvalue, со структурой или типом объединения (C 2018 6.2.4.8), а ++ определено только для вещественных типов или типов указателей (6.5.3.1 1). Во-вторых, даже если бы это было временно, это было бы неуместно, потому что мы обсуждаем не то, что делает стандарт C, а то, что стандарт C должен сказать, если бы он был изменен таким образом. результат ++ был lvalue. В таком случае она не будет временной. - person Eric Postpischil; 28.06.2019
comment
@ user6556709: В качестве доказательства это было бы технически осуществимым изменением стандарта C и не нарушило бы фундаментально язык, обратите внимание, что его можно реализовать с помощью #define pp(x) (*(++(x), &(x))). С этим определением pp действует так же, как гипотетический ++: pp(x) применяет ++ к x и создает lvalue для x. Следовательно, это возможная операция в C, и тот факт, что ++ не указан таким образом, является лишь вопросом выбора, а не технической необходимости. - person Eric Postpischil; 28.06.2019
comment
@GemTaylor: Извините, я неправильно пометил этот комментарий; это было для пользователя 6556709. int x; (x = 1) = 2; неверно C; присваивание не создает lvalue. - person Eric Postpischil; 28.06.2019
comment
@ user6556709: Мне пришло в голову, что вы, возможно, думали, что создаваемое значение lvalue будет значением какого-то временного объекта. Это не так. Идея состоит в том, что ++a будет возвращать lvalue для a. Не было бы временного объекта. - person Eric Postpischil; 28.06.2019