This just puzzled me:
#include <stdio.h>
int main(int argc, char** argv) {
int a = 0, b = 1;
int *ptr = argc <= 1 ? &a : &b;
(*ptr)++; //does work, of course
(*(argc <= 1 ? &a : &b))++; //inlining, does also work
int *ptr_a = &a;
int *ptr_b = &b;
(*(argc <= 1 ? ptr_a : ptr_b))++; //variables carry "assignability"
(argc <= 1 ? *ptr_a : *ptr_b)++; //if-expression does not carry "assignability"?
return 0;
}
I always assumed that "assignability" is a type-property. Hence I thought the last statement should work just fine, instead it is rejected. So why does the dereference have to be the outermost operator for a C-compiler to figure out that the lhs is actually a memory location?
edit: I doubt it has something to do with OS/compiler but the C standard, but here is my compiler setup:
clang version 3.3 (tags/RELEASE_33/final)
Target: x86_64-redhat-linux-gnu
Thread model: posix
And here is the error:
test.c:15:32: error: expression is not assignable
(argc <= 1 ? *ptr_a : *ptr_b)++; //if-expression does not carry "assignability"?
edit2: What interests me most is, why C seems to carry the "assignability" property through some but not all expressions.
The problem is that the conditional operator in C promotes the 2nd and 3rd operands to match each other. A promoted variable is a rvalue and not a lvalue, so the ?: always returns a rvalue.
The * operator on the other hand, returns a lvalue. That is why (*(argc <= 1 ? ptr_a : ptr_b))++
works, because ++ is applied to the result of * which is a lvalue.
But in the case of (argc <= 1 ? *ptr_a : *ptr_b)
the result is a rvalue so ++ cannot be used.