Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The * token in C is a context-dependent symbol that serves four distinct syntactic and semantic roles: as a unary indirection (dereference) operator, as a pointer declarator in type definitions, as a binary arithmetic multiplication operator, and as an unspecified variable-length array (VLA) size indicator in function prototypes. The compiler determines the token’s function based on its lexical position within an expression or declaration.

1. Unary Indirection (Dereference) Operator

When used as a unary operator preceding an expression, * performs indirection. It accesses the memory address stored in its operand and evaluates to the entity located at that address. Syntax:
*operand
Technical Semantics:
  • Operand Requirement: The operand must have a pointer type.
  • Return Value:
    • If the operand is a pointer to a function, the expression yields a function designator.
    • If the operand is a pointer to void, the expression yields a void expression. Because the C standard (C11 6.3.2.1) explicitly defines an lvalue as an expression with an object type other than void, dereferencing a void * does not yield an lvalue.
    • If the operand is a pointer to any other object type T (whether complete or incomplete), the expression yields an lvalue of type T. Dereferencing a pointer to an incomplete type is syntactically valid and does not violate constraints (e.g., &*ptr is legal because the lvalue is never evaluated to access the object).
  • Modifiability: Yielding an lvalue does not guarantee assignability. If the pointed-to type T is const-qualified, dereferencing yields a non-modifiable lvalue, which will cause a compiler error if placed on the left side of an assignment.
  • Precedence: It has high precedence (Level 2), associating right-to-left.
  • Undefined Behavior: Applying the indirection operator to a null pointer, an uninitialized pointer, or a pointer to an invalid memory address results in undefined behavior.
Syntax Visualization:
int val = 100;
int *ptr = &val;
*ptr = 200; /* Yields a modifiable lvalue of type 'int' */

void *v_ptr = &val;
/* *v_ptr; -> Yields a void expression, not an lvalue */

struct OpaqueStruct *inc_ptr;
/* &*inc_ptr; -> Valid syntax; yields an lvalue of an incomplete type, immediately consumed by & */

2. Pointer Declarator

When used in a declaration statement, * acts as a declarator modifier rather than an executable operator. It instructs the compiler that the identifier being declared is a pointer to the specified base type. Syntax:
type *identifier;
Technical Semantics:
  • Binding: In C, the * token binds syntactically to the identifier (the declarator), not the type specifier.
  • Type Derivation: It derives a pointer type from the base type. Multiple * tokens can be chained to declare pointers to pointers (e.g., int **ptr).
  • Qualifiers: Type qualifiers (like const or volatile) placed after the * apply to the pointer itself, whereas qualifiers before the * apply to the pointed-to type.
Syntax Visualization:
int *p1, p2;        /* p1 is a pointer to int; p2 is a standard int */
const int *p3;      /* Pointer to a constant int */
int * const p4;     /* Constant pointer to a mutable int */

3. Binary Multiplication Operator

When placed between two operands, * functions as the binary arithmetic multiplication operator. Syntax:
operand1 * operand2
Technical Semantics:
  • Operand Requirement: Both operands must be of arithmetic types (integer or floating-point).
  • Type Conversion: The operands are subject to the usual arithmetic conversions before the operation is performed. The result type matches the promoted type of the operands.
  • Precedence: It has multiplicative precedence (Level 3), associating left-to-right, which is lower than the unary indirection operator but higher than addition and subtraction.
  • Overflow: If the mathematical result cannot be represented by the resulting type, integer overflow occurs (which is undefined behavior for signed integers and wraps around for unsigned integers).
Syntax Visualization:
int a = 5;
int b = 10;
int product = a * b; /* Binary arithmetic evaluation */

4. Unspecified Variable Length Array (VLA) Size Indicator

Introduced in C99, the * token can be used within the array brackets of a function prototype declaration to denote a variable-length array of an unspecified size. Syntax:
type identifier[*]
type identifier[size][*]
Technical Semantics:
  • Context Restriction: This usage is strictly limited to function prototype declarations (not function definitions).
  • Type Compatibility: It serves as a syntactic placeholder indicating that the parameter is a VLA. It allows the compiler to perform type compatibility checking for multi-dimensional arrays where the inner dimensions are variable, without requiring the parameter names of the sizes to be specified in the prototype.
  • Evaluation: It does not evaluate to a value or perform any operation at runtime.
Syntax Visualization:
/* Prototype using '*' to indicate a VLA of unspecified size */
void process_matrix(int rows, int cols, int matrix[rows][*]);
Master C with Deep Grasping Methodology!Learn More