C and C++ have a number of constructs that make the grammar ambiguous and the source hard to parse. As a result, C and C++ parsers cannot be purely context-free and needs to consult symbol tables or use disambiguation.

Pointer/Typedef

Perhaps the most well-known. Is the following

a * b

a multiplication or a pointer (if a is a type)?

Sizeof

See: sizeof is surprisingly difficult to parse in c

sizeof is either a unary operator, or a parenthesized type name.

Example:

sizeof(int){0}

Is it

(sizeof(int)){0}

or

sizeof((int){0})

where (int){0} is compound literal?

C++ Templates and >>

Another well-known example. E.g. std::vector<std::vector<int>>

C++ Attributes Vs Array index/nested Lambda

See this Lobsters comment

Example:

int f() {
    int array[5];
    // failed to compile
    return array[[](){ return 0; }()];
}

See Also