expr_precedence.c revision 1.10 1 /* $NetBSD: expr_precedence.c,v 1.10 2022/08/25 19:03:48 rillig Exp $ */
2 # 3 "expr_precedence.c"
3
4 /*
5 * Tests for the precedence among operators.
6 */
7
8 int var;
9
10 /*
11 * An initializer needs an assignment-expression; the comma must be
12 * interpreted as a separator, not an operator.
13 */
14 /* expect+1: error: syntax error '4' [249] */
15 int init_error = 3, 4;
16
17 /* expect+1: error: non-constant initializer [177] */
18 int init_syntactically_ok = var = 1 ? 2 : 3;
19
20 /*
21 * The arguments of __attribute__ must be constant-expression, as assignments
22 * don't make sense at that point.
23 */
24 void __attribute__((format(printf,
25 /*
26 * Inside of __attribute__((...)), symbol lookup works differently. For
27 * example, 'printf' is a keyword, and since all arguments to
28 * __attribute__ are constant expressions, looking up global variables
29 * would not make sense. Therefore, 'var' is undefined.
30 *
31 * See lex.c, function 'search', keyword 'in_gcc_attribute'.
32 */
33 /* expect+1: error: syntax error '=' [249] */
34 var = 1,
35 /* Syntactically ok, must be a constant expression though. */
36 var > 0 ? 2 : 1)))
37 my_printf(const char *, ...);
38
39 void
40 assignment_associativity(int arg)
41 {
42 int left, right;
43
44 /*
45 * Assignments are right-associative. If they were left-associative,
46 * the result of (left = right) would be an rvalue, resulting in this
47 * error message: 'left operand of '=' must be lvalue [114]'.
48 */
49 left = right = arg;
50
51 left = arg;
52 }
53
54 void
55 conditional_associativity(_Bool cond1, _Bool cond2, int a, int b, int c)
56 {
57 /* The then-expression can be an arbitrary expression. */
58 var = cond1 ? cond2 ? a : b : c;
59 var = cond1 ? (cond2 ? a : b) : c;
60
61 /* The then-expression can even be a comma-expression. */
62 var = cond1 ? cond2 ? a, b : (b, a) : c;
63
64 var = cond1 ? a : cond2 ? b : c;
65 /*
66 * In almost all programming languages, '?:' is right-associative,
67 * which allows for easy chaining.
68 */
69 var = cond1 ? a : (cond2 ? b : c);
70 /*
71 * In PHP, '?:' is left-associative, which is rather surprising and
72 * requires more parentheses to get the desired effect.
73 */
74 var = (cond1 ? a : cond2) ? b : c;
75 }
76