/* $NetBSD: expr_precedence.c,v 1.12 2024/05/01 07:40:11 rillig Exp $ */ # 3 "expr_precedence.c" /* * Tests for the precedence among operators. */ /* lint1-extra-flags: -X 351 */ int var; /* * An initializer needs an assignment-expression; the comma must be * interpreted as a separator, not an operator. */ /* expect+1: error: syntax error '4' [249] */ int init_error = 3, 4; /* expect+1: error: non-constant initializer [177] */ int init_syntactically_ok = var = 1 ? 2 : 3; /* * The arguments of __attribute__ must be constant-expression, but for * simplicity of implementation, they are parsed just like function arguments, * even though this allows assignment-expression. */ void __attribute__((format(printf, /* * Inside of __attribute__((...)), symbol lookup works differently. For * example, 'printf' is a keyword, and since all arguments to * __attribute__ are constant expressions, looking up global variables * would not make sense. Therefore, 'var' is undefined. * * See lex.c, function 'search', keyword 'in_gcc_attribute'. */ var = 1, /* Syntactically ok, must be a constant expression though. */ var > 0 ? 2 : 1))) my_printf(const char *, ...); void assignment_associativity(int arg) { int left, right; /* * Assignments are right-associative. If they were left-associative, * the result of (left = right) would be an rvalue, resulting in this * error message: 'left operand of '=' must be lvalue [114]'. */ left = right = arg; left = arg; } void conditional_associativity(_Bool cond1, _Bool cond2, int a, int b, int c) { /* The then-expression can be an arbitrary expression. */ var = cond1 ? cond2 ? a : b : c; var = cond1 ? (cond2 ? a : b) : c; /* The then-expression can even be a comma-expression. */ var = cond1 ? cond2 ? a, b : (b, a) : c; var = cond1 ? a : cond2 ? b : c; /* * In almost all programming languages, '?:' is right-associative, * which allows for easy chaining. */ var = cond1 ? a : (cond2 ? b : c); /* * In PHP, '?:' is left-associative, which is rather surprising and * requires more parentheses to get the desired effect. */ var = (cond1 ? a : cond2) ? b : c; }