Skip to content

Instantly share code, notes, and snippets.

@syukronrm
Last active August 27, 2020 00:18
Show Gist options
  • Save syukronrm/d2af864f914ca7db6f1fc39415c35ba8 to your computer and use it in GitHub Desktop.
Save syukronrm/d2af864f914ca7db6f1fc39415c35ba8 to your computer and use it in GitHub Desktop.

This code works in C++.

#include <stdio.h>
#include <stdlib.h>

int main() {
    int a = 100;
    int b = 200;
    int c = (a == 10 ? a : b) = 300;
    printf("%d\n", a);
    printf("%d\n", b);
    printf("%d\n", c);
}

Output:

100
300
300

But that same code doesn't work on C. It produces error.

main.c:10:31: error: expression is not assignable
    int c = (a == 10 ? a : b) = 300;
            ~~~~~~~~~~~~~~~~~ ^
1 error generated.
compiler exit status 1

But why?

Turns out C and C++ have different grammar rule.

Take a look at C reference [4], C only allow left operand to be unary level 2 expression and it produce r-value. Check this BNF rule from [2]:

assignment_expression
	: conditional_expression
	| unary_expression assignment_operator assignment_expression

I think that's quite natural. But C++ has different rule, it can produce l-value if it return a variable.

What happen when I change that line into

int c = (a == 100 ? a + 100 : b) = 300;

Pew! It produces this error because the conditional expression produce r-value.

/cplayground/code.cpp: In function 'int main()':
/cplayground/code.cpp:10:40: error: lvalue required as left operand of assignment
     int c = (a == 100 ? a + 100 : b) = 300;
                                        ^~~

After further googling, I found another explanation [5]

[1] C++ https://www.nongnu.org/hcb/#assignment-expression http://www.csci.csusb.edu/dick/c++std/cd2/gram.html

[2] C https://www.lysator.liu.se/c/ANSI-C-grammar-y.html#assignment-expression

[3] C++ operator precedence notes https://en.cppreference.com/w/cpp/language/operator_precedence#Notes

[4] https://en.cppreference.com/w/c/language/operator_precedence#cite_ref-4

[5] https://www.yhi.moe/en/2018/03/31/can-ternary-operators-be-an-lvalue-in-c-or-not.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment