C11 Fundamentals: The Standard, the Toolchain, and Program Structure
What C11 Is and Why It Matters
C11 (ISO/IEC 9899:2011) is the third major revision of the C standard. Candidates must know that it is a standard, not a compiler: conformance is a property of an implementation, and implementations advertise conformance through __STDC_VERSION__ with value 201112L. A frequent trap is confusing the version macro with __STDC__ (which indicates conformance generally) or assuming a compiler that accepts C11 syntax fully implements every optional feature.
Translation and Program Structure
Understand the phases of translation: source characters are mapped, line splicing removes backslash-newline, tokens are formed, preprocessing runs, and only then does compilation begin. Know that main returns int and that reaching the closing brace of main returns 0. Declarations versus definitions, linkage (external, internal, none), and storage duration (automatic, static, thread, allocated) are core vocabulary.
The Trap Zones
Questions often probe: whether a feature is mandatory or optional (variable length arrays and complex types are optional in C11; _Atomic, _Thread_local, and anonymous struct/union members are mandatory); whether inline changes linkage (it does not by itself); and whether a declaration without a definition is an error (it is not, until the identifier is odr-like used).
Rule of Thumb
When a question asks "is this valid C11?", separate syntax accepted by the compiler from behavior guaranteed by the standard. Undefined behavior is still "valid C11" in the sense that the standard imposes no requirements; a diagnostic is not required. Worked example: int a[n]; where n is a runtime value is a variable length array. It is valid only if the implementation defines __STDC_NO_VLA__ as absent; if that macro is defined, the construct is not supported. Never assume VLA support unconditionally.
Types, Objects, and Conversions in C11
The Type System
Candidates must command the basic type categories: void, arithmetic (integer and floating), and derived types (pointers, arrays, functions, structures, unions). Distinguish object type from function type and incomplete type. void is an incomplete type that cannot be completed. An array of unknown size is incomplete until completed by an initializer or a prior declaration.
Integer Conversions and Promotions
The integer promotion rules and the usual arithmetic conversions are heavily tested. Integer promotions convert types of rank less than int to int if int can represent all values, otherwise to unsigned int. The usual arithmetic conversions then find a common type, with signedness subtleties: if the unsigned type has rank greater than or equal to the signed type, the signed operand converts to unsigned. Classic trap: comparing -1 with an unsigned value yields true because -1 converts to the maximum unsigned value.
Representation and Aliasing
Know that signed integer overflow is undefined behavior while unsigned arithmetic wraps modulo 2^N. Know the strict aliasing rule: an object may be accessed through a compatible type, a qualified version, a signed/unsigned counterpart, an aggregate containing it, or a character type. Accessing through an unrelated pointer type is undefined behavior, which is why memcpy is the portable pun.
Rule of Thumb
Before predicting a comparison's result, ask: "What is the common type after promotions?" Worked example: unsigned u = 1; int i = -2; then i < u is false, because i converts to a large unsigned value. If you instead cast u to int, the comparison is true. Always resolve the common type first, then evaluate.
Expressions, Operators, and Evaluation Order
Operator Semantics
Candidates need precise knowledge of precedence, associativity, and evaluation order. Precedence and associativity determine grouping; they do not determine evaluation order. The standard specifies sequencing only at sequence points (in C11 terminology, sequenced-before relationships), such as the end of a full expression, the &&, ||, and ?: operators, and function-call boundaries.
Undefined Behavior in Expressions
Classic traps: modifying an object twice between sequence points (i = i++ + 1;), modifying and reading without sequencing, and division by zero. Also know that &&, ||, and ?: short-circuit, while bitwise &, | do not. The comma operator sequences its left operand before its right and yields the right value; it is not the same as the comma separating function arguments.
Shifts, Sizes, and Casts
Know that shifting by a negative count or by a count greater than or equal to the width of the promoted left operand is undefined behavior. Left-shifting a negative value is undefined. sizeof yields size_t and does not evaluate its operand when the operand is a type name; applied to a VLA it may evaluate the size expression. Casts to pointer types and void * conversions are implicit both ways for object pointers, but not for function pointers.
Rule of Thumb
When a question shows a compound expression, first mark sequence points, then check for double modification. Worked example: int i = 5; int j = i++ + i++; has undefined behavior because i is modified twice without an intervening sequence point; the answer is not "12" or "11" but "undefined."
Control Flow, Functions, and Storage Duration
Statements and Scope
Know the statement categories: labeled, compound, expression, selection, iteration, and jump. Understand block scope, function scope (labels), file scope, and function prototype scope. switch requires an integer controlling expression; case labels are integer constant expressions; default may appear anywhere. A trap: case labels do not create scopes, so declarations inside a switch body need braces.
Functions and Linkage
Understand prototypes, default argument promotions (arguments of type float promote to double; small integers promote to int), and the fact that calling a function without a visible prototype in C11 is a constraint violation. static at file scope gives internal linkage; at block scope it gives static storage duration. _Noreturn marks functions that never return, and _Thread_local gives thread storage duration.
Storage Duration and Initialization
Automatic objects have indeterminate values unless initialized. Static-storage objects are zero-initialized before program startup. Designated initializers (.field = value, [index] = value) are C99 features retained in C11 and are frequently tested alongside compound literals, which create unnamed objects with the lifetime of the enclosing block.
Rule of Thumb
Ask two questions of any declaration: "What is its linkage?" and "What is its storage duration?" Worked example: static int counter; inside a function has no linkage, static storage duration, and is zero-initialized once; it persists across calls but is invisible outside the function. Confusing this with internal linkage is a common trap.
Pointers, Arrays, and the C11 Library
Pointer and Array Relationships
Understand array-to-pointer decay, pointer arithmetic within an array object (one past the end is valid to form but not to dereference), and the equivalence of a[i], *(a+i), and i[a]. Traps include assuming sizeof on a function parameter yields the array size (it yields pointer size), and assuming multidimensional arrays are pointer-to-pointer (they are not).
The Standard Library
Know the mandatory headers and their roles: <stdio.h>, <stdlib.h>, <string.h>, <stdint.h>, <stdatomic.h>, <threads.h>, <stdalign.h>, <stdnoreturn.h>, and <uchar.h>. C11 additions include aligned_alloc, quick_exit/at_quick_exit, timespec_get, anonymous structures and unions, static assertions (_Static_assert), and alignment facilities (_Alignas, _Alignof, max_align_t). Know that gets was removed in C11. Bounds-checking interfaces (_s functions) are optional (Annex K), not mandatory.
Rule of Thumb
When asked "does this function exist in C11?", classify it: mandatory, optional annex, or removed. Worked example: aligned_alloc(alignment, size) requires size to be a multiple of alignment; otherwise behavior is undefined. Many candidates assume any size works. Always check the preconditions before declaring a call correct.