# C syntax

The syntax of the C programming language is the set of lexical rules, grammar productions, and constraints that define how C source code is written and how a conforming compiler must read it. It is specified normatively in ISO/IEC 9899, the international C standard, whose language clause presents the grammar in a notation adapted from the C Reference Manual written by the language's creator, [Dennis Ritchie](https://www.edgepedia.org/dennis-ritchie)<sup>[1](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3088.pdf)</sup>. The standard is maintained by ISO/IEC JTC1/SC22/WG14, the international standardization working group for C<sup>[2](https://open-std.org/jtc1/sc22/wg14)</sup>, and the current edition is C23, ISO/IEC 9899:2024, adopted by ISO and IEC in 2024<sup>[2](https://open-std.org/jtc1/sc22/wg14)</sup>.

| Key fact | Detail |
|---|---|
| Steward | ISO/IEC JTC1/SC22/WG14, the working group for the programming language C<sup>[2](https://open-std.org/jtc1/sc22/wg14)</sup> |
| Current edition | C23, ISO/IEC 9899:2024, adopted in 2024; the next edition, C2y, is in development<sup>[2](https://open-std.org/jtc1/sc22/wg14)</sup><sup> • </sup><sup>[3](https://open-std.org/jtc1/sc22/wg14/www/projects.html)</sup>  |
| Revision history | C89 (ANSI X3.159-1989), C90, C95, C99, C11, C17, C23<sup>[3](https://open-std.org/jtc1/sc22/wg14/www/projects.html)</sup> |
| Not a context-free language | The meaning of an identifier depends on whether it has been declared as a `typedef` name, so parsers must consult a live typedef table while parsing<sup>[4](https://github.com/anthropics/claudes-c-compiler/blob/main/src/frontend/parser/README.md)</sup> |
| C23 keywords | `alignas`, `alignof`, `bool`, `false`, `static_assert`, `thread_local`, `true` become keywords<sup>[5](https://gcc.gnu.org/projects/c-status.html)</sup> |
| C23 removals | Old-style function definitions with identifier lists and unprototyped declarations are removed<sup>[5](https://gcc.gnu.org/projects/c-status.html)</sup> |
| Translation phases | Line splicing, tokenization with comment removal, and macro expansion occur in a specified order before semantic analysis<sup>[6](https://open-std.org/jtc1/sc22/wg14/www/docs/n843.htm)</sup> |
| Compiler support | GCC supports ISO C23 via the `-std=c23` and `-std=gnu23` options added in GCC 14, and C23 mode is the default since GCC 15<sup>[5](https://gcc.gnu.org/projects/c-status.html)</sup> |

## The standard's description of the syntax

The C standard specifies the form and interpretation of C programs: the representation of C programs, the syntax and constraints of the language, the semantic rules for interpreting them, and the restrictions and limits a conforming implementation must impose<sup>[6](https://open-std.org/jtc1/sc22/wg14/www/docs/n843.htm)</sup>. Its purpose is stated as promoting the portability, reliability, maintainability, and efficient execution of C programs across computing systems<sup>[7](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf)</sup>.

The standard treats translation as a sequence of phases: physical source lines are mapped to the source character set and spliced where a backslash ends a line; the file is decomposed into preprocessing tokens and white space, with each comment replaced by a space; preprocessing directives are executed and macro invocations are expanded; and only then is the token sequence processed as C<sup>[6](https://open-std.org/jtc1/sc22/wg14/www/docs/n843.htm)</sup>. The standard is designed for implementors and knowledgeable programmers, and it explicitly states that it is not a tutorial<sup>[7](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf)</sup>.

The standard also classifies behavior the syntax does not pin down. Undefined behavior covers erroneous constructs on which the standard imposes no requirements, such as integer overflow; unspecified behavior covers cases where two or more outcomes are allowed, such as the evaluation order of function arguments; implementation-defined behavior covers choices an implementation must document, such as the propagation of the high-order bit when a signed integer is shifted right<sup>[6](https://open-std.org/jtc1/sc22/wg14/www/docs/n843.htm)</sup>.

## Grammar and parsing

C's grammar is presented as productions in the standard, but the language it describes is not context-free. The decisive case is the typedef: whether an identifier names a type or an ordinary value depends on prior declarations in the translation unit, so a parser must consult a live typedef table as it reads, something awkward to express in a purely declarative grammar file<sup>[4](https://github.com/anthropics/claudes-c-compiler/blob/main/src/frontend/parser/README.md)</sup>. A `(` token can begin a cast expression, a compound literal, a parenthesized expression, or a parenthesized declarator, and hand-written parsers resolve these cases with speculative parsing, trying one interpretation and backtracking on failure<sup>[4](https://github.com/anthropics/claudes-c-compiler/blob/main/src/frontend/parser/README.md)</sup>.

**Operator precedence** is a practical consequence of the grammar. The GNU C Language Manual lists a usable subsequence of the precedence ordering, from highest to lowest: postfix operations (field access with `.` and `->`, array subscripting, function calls), unary prefix operations, multiplication, division, and remainder, addition and subtraction, comparisons, the logical operators `&&` and `||`, the conditional expression, assignments, and the comma operator<sup>[8](https://www.gnu.org/software/c-intro-and-ref/manual/c-intro-and-ref.html)</sup>. It advises that when two comparison operations are used together, or when `&&` and `||` are combined, parentheses should make the nesting explicit rather than relying on the grammar's fine distinctions<sup>[8](https://www.gnu.org/software/c-intro-and-ref/manual/c-intro-and-ref.html)</sup>. The same manual notes that `&&` guarantees to skip its right operand when the left one is false, which is why an expression such as `r != 0 && x % r == 0` never divides by zero<sup>[8](https://www.gnu.org/software/c-intro-and-ref/manual/c-intro-and-ref.html)</sup>.

Dennis Ritchie, who developed C at [Bell Labs](https://www.edgepedia.org/bell-labs) in the early 1970s, later characterized the language as "quirky, flawed, and an enormous success", citing its strange syntax and confusing declarations among the quirks<sup>[9](https://www.techradar.com/pro/c-is-quirky-flawed-and-an-enormous-success-quote-of-the-day-by-the-creator-of-the-programming-language-dennis-ritchie)</sup>.

## How the syntax reached its present form

The original language was developed by Ritchie between 1971 and 1973, and it became widely known through *The C Programming Language* by [Brian Kernighan](https://www.edgepedia.org/brian-kernighan) and Dennis Ritchie, published in 1978; the pre-standard version is called K&R C<sup>[10](https://www.cs.rhul.ac.uk/research/languages/projects/grammars/c/index.html)</sup>. By the early 1980s usage was widespread enough to merit formal standardization: ANSI established the X3J11 committee in 1983, the standard X3.159-1989 was produced in 1989, and ISO ratified it the following year as ISO/IEC 9899:1990<sup>[10](https://www.cs.rhul.ac.uk/research/languages/projects/grammars/c/index.html)</sup>. A 1995 amendment added support for international character sets but did not change the grammar<sup>[10](https://www.cs.rhul.ac.uk/research/languages/projects/grammars/c/index.html)</sup>.

Standardization changed the declaration syntax. The ANSI process augmented the syntax for parameter declarations to include the prototype style used in C++, while continuing to permit the older K&R interface<sup>[11](https://snscourseware.org/snsrcas/files/CW_5d172dbc690c2/History%20of%20C%20Programming-converted.pdf)</sup>.

WG14 has produced the revision sequence C90, C95, C99, C11, C17, and C23, with C2y under development and no publication yet available<sup>[3](https://open-std.org/jtc1/sc22/wg14/www/projects.html)</sup>. The committee also processes change and clarification requests, previously called defect reports, against each published edition of the standard<sup>[3](https://open-std.org/jtc1/sc22/wg14/www/projects.html)</sup>. The informal name of the current edition was itself settled by committee: WG14 took a vote to make the nickname "C23" official, preferring it to "C24"<sup>[12](https://www.open-std.org/jtc1/sc22/WG14/www/docs/n3372.pdf)</sup>.

## Changes in C23

C23, published as ISO/IEC 9899:2024, made visible changes to the syntax programmers write<sup>[2](https://open-std.org/jtc1/sc22/wg14)</sup>. The words `alignas`, `alignof`, `bool`, `false`, `static_assert`, `thread_local`, and `true` become keywords in their own right rather than macros from headers<sup>[5](https://gcc.gnu.org/projects/c-status.html)</sup><sup> • </sup><sup>[13](https://en.cppreference.com/c/23)</sup>. The predefined macro `__STDC_VERSION__` is bumped to `202311L`<sup>[13](https://en.cppreference.com/c/23)</sup>.

C23 also removes long-standing syntax: function definitions with identifier lists, the old K&R style, and function declarations whose parameter list is empty, which are now treated the same as a parameter list containing only `void`<sup>[5](https://gcc.gnu.org/projects/c-status.html)</sup>. cppreference's C23 page lists further removals: representations for signed integers other than two's complement, mixed wide string literal concatenation, and support for calling `realloc()` with zero size, whose behavior becomes undefined<sup>[13](https://en.cppreference.com/c/23)</sup>.

Support arrived quickly in major compilers. GCC added the new keywords in version 13, removed old-style function definitions in version 10, and introduced the `-std=c23` and `-std=gnu23` command-line options in GCC 14; since GCC 15, C23 mode is the default<sup>[5](https://gcc.gnu.org/projects/c-status.html)</sup><sup> • </sup><sup>[14](https://gcc.gnu.org/gcc-14/changes.html)</sup>.

## Grammar work in progress

The grammar continues to be a topic of committee proposals even between editions. A 2024 proposal for C2y introduced an `elementsof` operator to give array-element counts alongside `sizeof`, noting that "C23 seems to have shifted away from uglified keywords" and defaulting to the plain keyword name directly<sup>[15](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3313.pdf)</sup>. The C23 charter itself framed the revision around influences including the evolution of C-like languages such as C++, Java, and C#, the rising security threat on the Internet, and increased awareness of programming language vulnerabilities<sup>[16](https://open-std.org/jtc1/sc22/wg14/www/docs/n2611.htm)</sup>.

## References

1. [WG14 N3088, C standard draft, Introduction note on Clause 6](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3088.pdf)
2. [ISO/IEC JTC1/SC22/WG14 homepage](https://open-std.org/jtc1/sc22/wg14)
3. [WG14 Project status and milestones](https://open-std.org/jtc1/sc22/wg14/www/projects.html)
4. [claudes-c-compiler, parser README, typedef and ambiguity notes](https://github.com/anthropics/claudes-c-compiler/blob/main/src/frontend/parser/README.md)
5. [C Standards Support in GCC, GNU Project](https://gcc.gnu.org/projects/c-status.html)
6. [WG14 N843, C99 Committee Draft, clauses 1, 3, 4, 5](https://open-std.org/jtc1/sc22/wg14/www/docs/n843.htm)
7. [ISO/IEC 9899:2024, N3220 working draft, Abstract and Scope](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3220.pdf)
8. [GNU C Language Manual, Logical Operators and Comparisons](https://www.gnu.org/software/c-intro-and-ref/manual/c-intro-and-ref.html)
9. [TechRadar Pro, Ritchie quote of the day on C's quirks](https://www.techradar.com/pro/c-is-quirky-flawed-and-an-enormous-success-quote-of-the-day-by-the-creator-of-the-programming-language-dennis-ritchie)
10. [Royal Holloway grammars project, C language history and grammars](https://www.cs.rhul.ac.uk/research/languages/projects/grammars/c/index.html)
11. [History of C Programming, courseware PDF](https://snscourseware.org/snsrcas/files/CW_5d172dbc690c2/History%20of%20C%20Programming-converted.pdf)
12. [WG14 N3372, proposal on official standard titles](https://www.open-std.org/jtc1/sc22/WG14/www/docs/n3372.pdf)
13. [C23, cppreference.com](https://en.cppreference.com/c/23)
14. [GCC 14 Release Series changes](https://gcc.gnu.org/gcc-14/changes.html)
15. [WG14 N3313, Proposal for C2y: elementsof](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3313.pdf)
16. [WG 14 N 2611, C23 Charter](https://open-std.org/jtc1/sc22/wg14/www/docs/n2611.htm)

---
*Topic: Encyclopedia › Society and history › Languages and linguistics › Linguistics › Formal and computational linguistics › Concrete syntax of programming and query languages*

*Initially written Sep 17, 2026 · Reviewed: Sep 30, 2026; Oct 25, 2026 · Edited: Sep 30, 2026; Oct 25, 2026 · Last review: Oct 25, 2026*

*Copyright 2026 EdgeChat AI, a subsidiary of Biostate AI.*

License: Edgepedia Community License 1.0, https://www.edgepedia.org/edgepedia/license
