๐งฎ 21. Operator Precedence & Associativity in C
When a C expression contains several operators, its meaning depends on how the operators and operands are grouped and how equal-precedence operators group together. These rules are described using operator precedence and operator associativity.
Determines the grouping when operators from different precedence levels appear together.
Determines grouping direction when operators with the same precedence are present.
Parentheses state the intended grouping directly and make an expression easier to read.
21.1 Why Do We Need Precedence?
Consider:
int result = 2 + 3 * 4; There are two operators: + and *. If addition happened first, the result would be:
(2 + 3) * 4 = 20 But multiplication has higher precedence than addition, so C groups the expression as:
2 + (3 * 4) Therefore:
2 + 12 = 14 Expression: 2 + 3 * 4 โ โผ * has higher precedence โ โผ 2 + (3 * 4) โ โผ 14 21.2 What Is Operator Precedence?
Operator precedence defines the relative priority of operators when an expression contains different operators.
For example:
* / % have higher precedence than:
+ - Therefore:
a + b * c is grouped as:
a + (b * c) not:
(a + b) * c 21.3 What Is Associativity?
Associativity determines how operators having the same precedence are grouped.
For example:
a - b + c The + and - operators have the same precedence and their associativity is left-to-right.
Therefore:
(a - b) + c is the grouping.
a - b + c โโโโโโโโโโโโโโโโโ โ Same precedenceโ โโโโโโโโโฌโโโโโโโโ โ โผ Left โ Right (a - b) + c 21.4 Precedence vs Associativity
| Concept | Question Answered | Example |
|---|---|---|
| Precedence | Which operator binds more strongly? | a + b * c |
| Associativity | How are equal-precedence operators grouped? | a - b + c |
| Parentheses | What grouping did the programmer explicitly request? | (a + b) * c |
21.5 C Operator Precedence Reference Table
The following table is a practical ordering from higher precedence to lower precedence.
| Level | Operators | Description | Associativity |
|---|---|---|---|
| 1 | () [] -> . ++ -- | Function call, array subscript, member access, postfix increment/decrement | Left โ Right |
| 2 | ++ -- + - ! ~ (type) * & sizeof _Alignof | Prefix increment/decrement, other unary operators, and casts | Right โ Left |
| 3 | * / % | Multiplication, division, remainder | Left โ Right |
| 4 | + - | Addition, subtraction | Left โ Right |
| 5 | << >> | Bitwise shift | Left โ Right |
| 6 | < <= > >= | Relational comparison | Left โ Right |
| 7 | == != | Equality comparison | Left โ Right |
| 8 | & | Bitwise AND | Left โ Right |
| 9 | ^ | Bitwise XOR | Left โ Right |
| 10 | | | Bitwise OR | Left โ Right |
| 11 | && | Logical AND | Left โ Right |
| 12 | || | Logical OR | Left โ Right |
| 13 | ?: | Conditional operator | Right โ Left |
| 14 | = += -= *= /= %=<<= >>= &= ^= |= | Assignment operators | Right โ Left |
| 15 | , | Comma operator | Left โ Right |
21.6 Parentheses Make Grouping Explicit
Parentheses explicitly group an expression.
int a = 2 + 3 * 4; int b = (2 + 3) * 4; Results:
a = 14 b = 20 21.7 Arithmetic Precedence
int result = 10 + 4 * 2; Multiplication comes first:
10 + (4 * 2) 10 + 8 18 Now consider:
int result = (10 + 4) * 2; Parentheses change the grouping:
14 * 2 28 21.8 Multiplication, Division and Remainder
The operators *, /, and % have the same precedence and associate from left to right.
int result = 20 / 5 * 2; Grouping:
(20 / 5) * 2 Result:
8 Not:
20 / (5 * 2) 21.9 Addition and Subtraction
int result = 20 - 5 + 2; Both operators have the same precedence and are left-associative.
(20 - 5) + 2 15 + 2 17 21.10 Relational Operators vs Equality Operators
Relational operators have higher precedence than equality operators.
a < b == c < d The relational comparisons are grouped first:
(a < b) == (c < d) A comparison produces int value 1 when true and 0 when false. In the next comparison, that 0 or 1 becomes an operand.
21.11 Logical AND vs Logical OR
Logical AND has higher precedence than logical OR.
a || b && c is grouped as:
a || (b && c) not:
(a || b) && c 21.12 Bitwise AND vs Logical AND
| Operator | Meaning | Precedence Level |
|---|---|---|
& | Bitwise AND | Higher than && |
&& | Logical AND | Lower than bitwise AND |
For example:
a & b == 0 Because equality has higher precedence than bitwise AND, the expression is grouped as:
a & (b == 0) This may be surprising. If the intended meaning is to test the bitwise result, write:
(a & b) == 0 21.13 Assignment Operators Are Right-Associative
a = b = c = 10; The grouping is:
a = (b = (c = 10)); Therefore c receives 10, then b, then a.
21.14 Chained Assignment
int a, b, c; a = b = c = 25; Conceptually:
c = 25 b = c a = b All three objects end up containing 25.
21.15 Conditional Operator Associativity
The conditional operator ?: is right-associative.
a ? b : c ? d : e is grouped as:
a ? b : (c ? d : e) Nested conditional expressions can become difficult to read, so parentheses are often useful.
21.16 Unary Operators and Right-to-Left Associativity
For a chain of prefix unary operators, start with the operator nearest the operand and work outward.
!~x can be understood as:
!(~x) Read the inner operation first to understand what value the outer operator uses.
21.17 Function Calls and Array Access
Function call and array subscript operators have very high precedence.
arr[i + 1] The expression between the brackets supplies the array index. The brackets form an array-access expression using arr.
Similarly:
printf("%d", a + b); The parentheses after the function name form a function call. Commas separate the arguments; they do not specify which argument is evaluated first.
21.18 Structure Member Access
The operators . and -> are among the highest precedence operators.
student.age studentPtr->age Parentheses can still be necessary when combining member access with other operators or pointer expressions.
21.19 Prefix vs Postfix Increment
++i i++ Both increment the object, but their values in an expression differ.
| Expression | Value Produced | Object Update |
|---|---|---|
++i | Updated value | Increment occurs before the value is used |
i++ | Previous value | Increment occurs as part of the postfix operation |
Postfix increment has higher precedence than prefix increment. This controls grouping, while the prefix/postfix rule determines whether the expression gives the new or old value.
21.20 Precedence Is Not Evaluation Order
For example, do not reason incorrectly from precedence alone about:
f() + g() The precedence of + does not tell you whether f() or g() is called first.
When the call order matters, call each function in a separate statement. Store the results and then calculate their sum.
21.21 Associativity Is Not Evaluation Order Either
Associativity answers a grouping question. It does not guarantee the execution order of separate function calls or other operands.
For example:
a - b - c is grouped as:
(a - b) - c because subtraction is left-associative.
For values already stored in variables, follow this grouping to calculate the answer. If the operands are function calls, do not assume that the leftmost call runs first.
21.22 A Complete Expression Trace
int result = 10 + 2 * 5 - 8 / 2; 10 + 2 * 5 - 8 / 2 โ โ โผ โผ 2 * 5 8 / 2 โ โ โผ โผ 10 4 Expression becomes: 10 + 10 - 4 + and - have equal precedence. Associativity = Left โ Right. (10 + 10) - 4 20 - 4 = 16 21.23 Another Expression Trace
int result = 8 + 4 * 3 - 6 / 2; Step 1:
4 * 3 = 12 6 / 2 = 3 Now:
8 + 12 - 3 Left-to-right for equal-precedence + and -:
(8 + 12) - 3 20 - 3 17 21.24 Parentheses Can Improve Readability
Compare:
if (a & mask == 0) with:
if ((a & mask) == 0) The second version communicates the intended grouping much more clearly.
21.25 Common Precedence Trap โ Arithmetic
int x = 2 + 3 * 4; Correct:
14 Incorrect assumption:
20 21.26 Common Precedence Trap โ Division and Multiplication
int x = 24 / 6 * 2; Both operators have the same precedence and are left-associative:
(24 / 6) * 2 4 * 2 8 21.27 Common Precedence Trap โ Logical Operators
if (age >= 18 && score >= 50 || bonus) Grouping:
((age >= 18) && (score >= 50)) || bonus Logical AND has higher precedence than logical OR.
21.28 Common Precedence Trap โ Assignment
if (x = 10) This condition assigns a value instead of comparing values. The assigned value becomes the condition: zero is false and a nonzero value is true. Use equality comparison when you only want to test the value.
For comparison, use:
if (x == 10) = assigns. == compares for equality. 21.29 Comma Operator
The comma operator has very low precedence compared with most other operators.
int x = (a = 5, b = 10, a + b); The comma operator evaluates the expressions from left to right and the value of the whole comma expression is the value of its rightmost operand.
Here:
a = 5 b = 10 a + b = 15 So:
x = 15 21.30 The Cast Operator
double result = (double)5 / 2; A cast groups tightly with its operand. Here, it converts 5 to double before division, so the division uses floating-point arithmetic.
Therefore:
(double)5 becomes a floating-point value before division.
Without the cast:
5 / 2 is integer division when both operands are integers.
21.31 Pointer Expressions and Precedence
Consider:
*p++ The postfix increment operator has higher precedence than unary dereference, so it is grouped as:
*(p++) It is not:
(*p)++ These expressions have different effects.
21.32 Another Pointer Example
(*p)++; Here parentheses force the dereferenced object to be incremented.
Compare:
*p++; which groups as:
*(p++); | Expression | Grouping | Main Effect |
|---|---|---|
*p++ | *(p++) | Use pointed value, then advance pointer |
(*p)++ | Explicitly dereference first | Increment pointed object |
21.33 Array and Pointer Precedence
*p[i] The array subscript operator has higher precedence than unary dereference. Therefore it is grouped as:
*(p[i]) not:
(*p)[i] Parentheses are required for the second interpretation.
21.34 Macro Expressions and Precedence
Precedence becomes especially important when writing C preprocessor macros.
Unsafe macro:
#define SQUARE(x) x * x Consider:
int result = SQUARE(5 + 1); Expansion:
5 + 1 * 5 + 1 Due to multiplication precedence:
5 + 5 + 1 = 11 Safe form:
#define SQUARE(x) ((x) * (x)) Expansion:
((5 + 1) * (5 + 1)) = 36 21.35 Side Effects in Expressions
Parentheses do not prevent a macro from using an argument twice. If the argument changes a variable, the expanded expression may have undefined behavior.
#define SQUARE(x) ((x) * (x)) int i = 5; int result = SQUARE(i++); Expansion:
((i++) * (i++)) The expression modifies i more than once without the sequencing required to make the behavior defined. The behavior is therefore undefined.
A function is often safer when an argument may have side effects:
static inline int square_int(int x) { return x * x; } 21.36 Precedence and the Conditional Operator
int max = a > b ? a : b; Relational comparison binds more strongly than the conditional operator, so the expression is effectively:
int max = (a > b) ? a : b; Adding parentheses can still improve readability.
21.37 Precedence and Assignment
x = a + b * c; Grouping:
x = (a + (b * c)); The multiplication is grouped before addition, and the resulting expression is then assigned to x.
21.38 How to Solve Precedence Questions
Expression | v Check parentheses | v Find higher-precedence operators | v Group equal-precedence operators using associativity | v Check casts / unary operators | v Check logical and relational grouping | v Check assignment | v Evaluate the grouped expression | v Final result 21.39 A Reliable Exam Method
- Write the expression clearly.
- Resolve explicit parentheses first.
- Identify the highest-precedence operators.
- Apply associativity where operators share precedence.
- Rewrite the expression with parentheses.
- Evaluate only after the grouping is clear.
- Check for side effects or undefined behavior.
21.40 Example โ Placement Style Question
int x = 5; int y = 2; int result = x + y * 3; Multiplication first:
5 + (2 * 3) 5 + 6 11 Therefore:
result = 11 21.41 Example โ Same Precedence
int result = 100 / 10 * 2; Because / and * have the same precedence:
(100 / 10) * 2 10 * 2 20 21.42 Example โ Logical Expression
int result = 1 || 0 && 0; AND first:
1 || (0 && 0) Then:
1 || 0 = 1 21.43 Example โ Comparison and Logical Operators
int result = 5 > 2 && 8 > 4; Comparisons are grouped before logical AND:
(5 > 2) && (8 > 4) Both comparisons are true, so:
1 && 1 = 1 21.44 Example โ Assignment Chain
int a, b, c; a = b = c = 50; Because assignment is right-associative:
a = (b = (c = 50)); Final values:
a = 50 b = 50 c = 50 21.45 Example โ Parentheses Change Everything
int a = 2; int b = 3; int c = 4; int x = a + b * c; int y = (a + b) * c; First:
x = 2 + (3 * 4) x = 14 Second:
y = (2 + 3) * 4 y = 20 21.46 Precedence vs Evaluation vs Sequencing
| Concept | Meaning |
|---|---|
| Precedence | Determines operator binding/grouping relative to other operators. |
| Associativity | Determines grouping among operators sharing a precedence level. |
| Evaluation order | Describes when operand expressions are evaluated. |
| Sequencing | Describes ordering relationships important for side effects. |
21.47 Conditional Expressions with Mixed Types
The conditional operator uses only the selected alternative, but both alternatives help determine the result type. For example, mixing -1 and 10U can make the result unsigned. The program below uses two int alternatives, so the selected value stays an int.
Complete C program:
#include <stdio.h>
int main(void)
{
int valid = 1;
int points = valid ? 10 : -1;
printf("Points = %d\n", points);
return 0;
}
Expected output:
Points = 10
Step-by-step explanation:
- Only the chosen second or third operand is evaluated.
- Both alternatives are int in this example, so no unsigned conversion is involved.
- The result is assigned to points.
21.48 Quick Revision
๐ Associativity โ Resolves operators of the same precedence.
๐ * / % โ Higher than + -
๐ + - โ Higher than relational operators
๐ < <= > >= โ Higher than == !=
๐ == != โ Higher than bitwise AND
๐ & โ Higher than ^
๐ ^ โ Higher than |
๐ | โ Higher than &&
๐ && โ Higher than ||
๐ Assignment โ Right-to-left
๐ Comma โ Lowest precedence
๐ Parentheses โ Use them to make intended grouping explicit.
๐ฌ Operator Precedence โ Expression Grouping
Follow how C groups 10 + 5 * 2 > 15 && 1
according to operator precedence.
๐ฌ Expression Grouping Visualizer
๐ Program Tracing โ Operator Precedence & Associativity
The combined expression is decomposed into clear steps so students can see the precedence relationship without relying on a tricky one-line statement.
โ
21.49 Quick MCQs
Select an answer first, then click Check Answer. A correct choice becomes green. If the answer is wrong, your choice becomes red and the correct option becomes green. The explanation appears below.
Multiplication has higher precedence than addition, assignment, and logical OR.
Multiplicative operators associate left-to-right.
Relational operators such as < have higher precedence than equality operators such as ==.
5 * 2 is grouped first, then 10 is added.
/ and * have the same precedence and associate left-to-right: (20 / 5) * 2 = 8.
Logical AND has lower precedence than equality.
Assignment operators associate right-to-left.
Addition has higher precedence than shift, so the expression is 1 << (2 + 1) = 8.
Postfix ++ has higher precedence than unary *, so *p++ means *(p++).
The comma operator has the lowest precedence among these operators.
21.50 ๐ฏ Practice Problems
Practice precedence, associativity, increments, pointer expressions, conditional and comma operators, parentheses, and safe expression analysis. Use ๐ป Solve It Yourself first, open Hint only when needed, and use Show Program after attempting the problem.
Problem 1: Find the output of the expression 10 + 5 * 2.
Input: No input.
Output: Print the evaluated result.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
printf("%d", 10 + 5 * 2);
return 0;
}
Problem 2: Find the output of the expression 20 / 5 * 2.
Input: No input.
Output: Print the evaluated result.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
printf("%d", 20 / 5 * 2);
return 0;
}
Problem 3: Evaluate the expression 10 + 5 > 12.
Input: No input.
Output: Print 1 for true or 0 for false.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
printf("%d", 10 + 5 > 12);
return 0;
}
Problem 4: Evaluate the expression 5 | 3 & 1.
Input: No input.
Output: Print the result.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
printf("%d", 5 | 3 & 1);
return 0;
}
Problem 5: Evaluate the expression 1 << 2 + 1.
Input: No input.
Output: Print the result.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
printf("%d", 1 << 2 + 1);
return 0;
}
Problem 6: Determine the result of 1 || 0 && 0.
Input: No input.
Output: Print 1 or 0.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
printf("%d", 1 || 0 && 0);
return 0;
}
Problem 7: Determine the values of a and b after a = b = 20.
Input: No input.
Output: Print a and b.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int a, b;
a = b = 20;
printf("a=%d b=%d", a, b);
return 0;
}
Problem 8: Find the output of a pre-increment expression using x = 5 and y = ++x.
Input: No input.
Output: Print x and y.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int x = 5;
int y = ++x;
printf("x=%d y=%d", x, y);
return 0;
}
Problem 9: Find the output of a post-increment expression using x = 5 and y = x++.
Input: No input.
Output: Print x and y.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int x = 5;
int y = x++;
printf("x=%d y=%d", x, y);
return 0;
}
Problem 10: Demonstrate the difference between *p++ and (*p)++ using an integer array.
Input: No input.
Output: Show the value read by *p++, the next pointed value, and the changed first element from (*p)++.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int a[] = {10, 20};
int *p1 = a;
int *p2 = a;
int first = *p1++;
int second = (*p2)++;
printf("first=%d next=%d second=%d a0=%d",
first, *p1, second, a[0]);
return 0;
}
Problem 11: Evaluate a nested conditional expression that assigns A for marks >= 90, B for marks >= 75, otherwise C.
Input: One integer marks.
Output: Print A, B, or C.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int marks;
scanf("%d", &marks);
char grade = marks >= 90 ? 'A' : marks >= 75 ? 'B' : 'C';
printf("%c", grade);
return 0;
}
Problem 12: Find the result of a comma operator expression where y = (x = 5, x + 3).
Input: No input.
Output: Print x and y.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int x, y;
y = (x = 5, x + 3);
printf("x=%d y=%d", x, y);
return 0;
}
Problem 13: Identify the precedence order in a + b * c - d by evaluating it for supplied values.
Input: Four integers a b c d.
Output: Print the result of a + b * c - d.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int a, b, c, d;
scanf("%d %d %d %d", &a, &b, &c, &d);
printf("%d", a + b * c - d);
return 0;
}
Problem 14: Identify the precedence order in a && b || c by evaluating it for supplied logical values.
Input: Three integers a b c.
Output: Print 1 or 0.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
printf("%d", a && b || c);
return 0;
}
Problem 15: Evaluate the expression 10 > 5 == 1.
Input: No input.
Output: Print the result.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
printf("%d", 10 > 5 == 1);
return 0;
}
Problem 16: Evaluate 5 & 3 == 1 and compare it with the clearer parenthesized expression (5 & 3) == 1.
Input: No input.
Output: Print both results.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int direct = 5 & 3 == 1;
int clear = (5 & 3) == 1;
printf("direct=%d clear=%d", direct, clear);
return 0;
}
Problem 17: Rewrite a complicated expression using parentheses to make its grouping clear: a + b * c > d && e.
Input: Five integers a b c d e.
Output: Print the result using explicit parentheses.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
int a, b, c, d, e;
scanf("%d %d %d %d %d", &a, &b, &c, &d, &e);
int result = (((a + (b * c)) > d) && e);
printf("%d", result);
return 0;
}
Problem 18: Explain why precedence does not determine the complete evaluation order of an expression by printing two concise statements.
Input: No input.
Output: Print the required explanation on two lines.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
printf("Precedence determines grouping.\n");
printf("Evaluation order determines when operands are evaluated.");
return 0;
}
Problem 19: Identify whether modifying the same variable multiple times in one unsequenced expression is well-defined. Do not execute undefined code.
Input: No input.
Output: Classify i = i++ + 1 as Undefined and two separate increment statements as Well-defined.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
printf("i = i++ + 1: Undefined\n");
printf("i++; i += 1;: Well-defined");
return 0;
}
Problem 20: Create a program containing ten defined but tricky C expressions, evaluate them, and print each result.
Input: No input.
Output: Print results E1 through E10, one per line.
C Code Editor
Sample Input
Program Output
Run your program to see the output.
Test Cases
#include <stdio.h>
int main()
{
printf("E1=%d\n", 10 + 5 * 2);
printf("E2=%d\n", 20 / 5 * 2);
printf("E3=%d\n", 10 + 5 > 12);
printf("E4=%d\n", 5 | 3 & 1);
printf("E5=%d\n", 1 << 2 + 1);
printf("E6=%d\n", 1 || 0 && 0);
printf("E7=%d\n", 10 > 5 == 1);
printf("E8=%d\n", (5 & 3) == 1);
printf("E9=%d\n", 2 + 3 << 1);
printf("E10=%d", 0 ? 10 : 20);
return 0;
}
21.51 Key Takeaway
Precedence = grouping priority.
Associativity = direction for equal-precedence operators.
*, /, % come before + and -.
Arithmetic operators come before relational operators.
Relational operators come before equality operators.
Bitwise AND comes before XOR, which comes before OR.
&& comes before ||.
Assignment associates right-to-left.
Postfix operators such as p++ bind very tightly.
Precedence is not the same as evaluation order.
Use parentheses when an expression may be difficult to understand.
๐ค Operator Precedence & Associativity โ Interview Questions
๐ก Operator Precedence & Associativity โ Placement Tips
- Memorize the major operator groups, but use parentheses whenever a reader could reasonably misinterpret an expression.
- When operators have the same precedence, check associativity: many arithmetic operators are left-to-right, while assignment is right-to-left.
- Do not confuse grouping with evaluation order; precedence does not guarantee which operand runs first.
- Be especially careful when mixing equality with bitwise operators, shifts with arithmetic, and pointer dereference with postfix increment.
- An expression with unsequenced changes to the same variable has undefined behavior. Identify the error instead of guessing a numeric output.
- In interviews, show the grouping first with parentheses, then evaluate the grouped expression step by step.
โ๏ธ Operator Precedence & Associativity โ Extra Practice Questions
- Parenthesize
a + b << c & dexactly as C groups it. - Compare
*p++,(*p)++,*++p, and++*pusing a small array. - Evaluate a mixed expression containing arithmetic, relational, equality, logical AND, and logical OR operators.
- Write a nested conditional expression, then rewrite it using if/else for readability.
- Find three expressions where adding parentheses changes the result.
- Review five expressions and identify which are merely tricky and which contain undefined behavior.