C Mastery / Expressions and Evaluation
Part 1 — The Core Language

Expressions and Evaluation

This chapter defines what an expression is in C, how expressions are evaluated to produce values, and the crucial distinction between an expression's *value* and its *side effects*. Every operator chapter that follows builds on this.

Why This Matters

C is an expression-oriented language. Assignments, function calls, arithmetic, and even some control-flow constructs are expressions. A precise model of "expression" and "evaluation" is required before sequencing, precedence, and undefined behavior make sense.

Prerequisites

Core Concept

What an expression is

An expression is a sequence of operators and operands that specifies computation of a value, designates an object or function, generates side effects, or does a combination of these.

Expressions are built from:

expressions, and (C99) compound literals.

Evaluation

Evaluating an expression produces a value or a designation, and may cause side effects (modifying an object, calling a function, doing I/O).

There is a critical distinction:

machine).

Example: in x = 5, the value of the whole expression is 5 (the assigned value), and the side effect is that the object x is modified.

lvalue expressions

An lvalue is an expression that potentially designates an object. Most object-typed expressions are lvalues (variable names, *p, array element access, struct member access). A modifiable lvalue is an lvalue that is not an array, not an incomplete type, and not const-qualified.

Syntax

Primary expressions:

identifier
constant        /* 42, 3.14, 'a' */
string-literal  /* "hello" */
( expression )
compound-literal /* (int){5} — C99 */

Compound expressions use operators, which are covered in c.core.9 through c.core.13.

Examples

Values vs. side effects

int x = 1;
int y = (x = 5);   /* value of (x = 5) is 5; side effect: x becomes 5 */
/* now x == 5, y == 5 */

Expressions as statements

In C, an expression followed by a semicolon is an expression statement:

x = 5;      /* expression statement */
f();        /* function call expression statement */
x++;        /* increment expression statement */

lvalues vs. non-lvalues

int a = 1;
int *p = &a;    /* a is an lvalue; &a is valid */
/* & (a + 1)   ERROR: (a + 1) is not an lvalue */

How It Works

The abstract machine evaluates expressions by combining the values of subexpressions according to operator semantics. In the absence of side effects, evaluation order for most operators is unspecified — only the *value computation* is constrained. This is the heart of c.ops.sequencing.

Two concepts govern evaluation:

The standard's *sequencing* rules say which evaluations happen before which. This is covered fully in c.core.13.

Variations

Full expressions and sequencing

A full expression is an expression that is not part of another expression (for example, an expression statement or the controlling expression of an if). There is a sequence point after each full expression.

Discarded-value expressions

Some expressions are evaluated only for their side effects; their value is discarded. An expression statement x++; is an example.

Common Mistakes

expressions are *parsed*, not the order subexpressions are *evaluated*.

(this is UB).

Undefined Behavior

side effect and a value computation using the same scalar object, is undefined behavior (c.ops.sequencing). VERIFIED

Portability

This means different compilers may legitimately produce different results for expressions that depend on unspecified evaluation order.

Under the Hood

The compiler parses an expression into an abstract syntax tree (AST), then lowers it to intermediate representation and machine code. Optimization transforms the tree/IR aggressively but must preserve observable behavior. The AST is also the subject of c.compiler.1.

Practical Usage

unsequenced modifications).

sequencing explicit.

Exercises

1. For each of x = 5, f(), *p, a + b, and "str", state whether it is an lvalue and whether it has side effects. 2. Write a program that demonstrates the value of an assignment expression by assigning the result to another variable. 3. Explain why &(a + 1) is illegal.

Deep Challenge

Using the C standard's definitions of "expression," "evaluation," "lvalue," and "side effect," explain precisely what is wrong with:

int i = 0;
int j = (i = 1) + (i = 2);

Identify whether this is undefined behavior, unspecified behavior, or implementation-defined, and cite the relevant rule category.

References

function designators).

Verification

verified.`

Progress

Concept checkboxes

Mastery levels

ConceptCurrent level (0–8)Target level
c.lang.expr05