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