-4

I have heard that ++a returns l-value in c wheres a++ returns r-value in c. Since ++a return l-value then why &(++a) throws complilation error?

Here's a link: Why is ++x a lvalue and x++ a rvalue?

#include<stdio.h>

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

Error message:

guess.c: In function ‘main’:
guess.c:6:4: error: lvalue required as unary ‘&’ operand
  p=&(++a);
Blaze
  • 16,736
  • 2
  • 25
  • 44
  • 10
    You're wrong: `++a` does not return an lvalue in C — so you're starting from a false premise, leading to a false conclusion. Note that your linked question is explicitly tagged [tag:c++] and [tag:c++11] — what applies in C++, especially in C++11 or later, very often does not apply to C, not even C11 or C17 (C18). – Jonathan Leffler Jun 28 '19 at 07:52
  • Why do you think a temporary can be a lvalue? – user6556709 Jun 28 '19 at 08:29
  • @Bathsheba it is not useful at all because if you google the error message along with the word "increment" you'll find out that it is a duplicate. That, coupled with a false premise without sources to it and there is not much left to salvage. – Antti Haapala -- Слава Україні Jun 28 '19 at 10:25
  • @Bathsheba that along with the error message rather explicitly spelling out that that which is given to `&` is, in fact, not an lvalue. – Antti Haapala -- Слава Україні Jun 28 '19 at 10:28
  • @AnttiHaapala: Well done; you've established yourself as being more experienced than the OP. – Bathsheba Jun 28 '19 at 10:28

1 Answers1

3

You're mixing up C with C++. In C++, you can indeed do that. In C, ++a just gives you the new value of a (an rvalue in C++ terms), and you can't take the address of that.

And of course, your print should be printf("%d\n", *p);, not printf("%d\n",p); (or printf("%p\n", (void *)p);, if you want to print the address of a).

Blaze
  • 16,736
  • 2
  • 25
  • 44
  • @EricPostpischil it would make no sense to define ++a returning a lvalue. It returns a temporary. Even in C++ naming convention a temporary can't be a lvalue. – user6556709 Jun 28 '19 at 08:26
  • @user6556709: It would make sense. Whether it produces a temporary is irrelevant. The C standard **could** say it produces (not returns; this is not a function call) an lvalue, and there is no technical impediment to implementing that. It simply does not. – Eric Postpischil Jun 28 '19 at 08:29
  • @EricPostpischil It is not irrelevant that the result is a temporary. It defines its life-time. Making it a lvalue would have some interesting impacts on the way how life-time is handled. – user6556709 Jun 28 '19 at 09:11
  • @user6556709 Why would it impact lifetime to "expose" (because in C it doesn't return) the actual item incremented? C++ seems to be quite happy? I'm just after detail? OK, you can say C++ is not C, but that doesn't actually explain anything. – Gem Taylor Jun 28 '19 at 10:44
  • @user6556709: First, you are wrong that the result of `++` is a temporary. The only temporary objects in C are non-lvalue expressions with structure or union type (C 2018 6.2.4. 8), and `++` is only defined for real or pointer types (6.5.3.1 1). Second, even if it were a temporary, that would be irrelevant because we are not discussing what the C standard **does** say but what the C standard **would** say if it were changed so the result of `++` were an lvalue. In that case, it would not be a temporary. – Eric Postpischil Jun 28 '19 at 11:43
  • 1
    @user6556709: As evidence this would be a technically feasible change to the C standard and would not fundamentally break the language, observe it can be implemented with `#define pp(x) (*(++(x), &(x)))`. With this definition, `pp` acts as the hypothetical `++` would: `pp(x)` applies `++` to `x` and produces an lvalue for `x`. Therefore, this is a possible operation in C, and the fact that `++` is not specified that way is only a matter of choice, not of technical necessity. – Eric Postpischil Jun 28 '19 at 11:51
  • 1
    @GemTaylor: Sorry, I tagged that comment wrong; it was for user6556709. `int x; (x = 1) = 2;` is not correct C; assignment does not produce an lvalue. – Eric Postpischil Jun 28 '19 at 13:54
  • @user6556709: It occurs to me you may have thought the lvalue to be produced would be that of some temporary object. It would not. The idea is that `++a` would return an lvalue for `a`. There would be no temporary object. – Eric Postpischil Jun 28 '19 at 13:54