Authors: Jay Ghiron
Date: 2026-09-10
Submitted against: C23
Status: Open
A strictly conforming program shall use only those features of the language and library specified in this document. It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior, and shall not exceed any minimum implementation limit.
(C23 4 "Conformance" paragraph 5.)
A conforming hosted implementation shall accept any strictly conforming program.
(C23 4 "Conformance" paragraph 7.)
The implementation shall be able to translate and execute a program that uses but does not exceed the following limitations for these constructs and entities:
- 127 nesting levels of blocks
- 63 nesting levels of conditional inclusion
- 12 pointer, array, and function declarators (in any combinations) modifying an arithmetic, structure, union, or
voidtype in a declaration- 63 nesting levels of parenthesized declarators within a full declarator
- 63 nesting levels of parenthesized expressions within a full expression
- 63 significant initial characters in an internal identifier or a macro name (each universal character name or extended source character is considered a single character)
- 31 significant initial characters in an external identifier (each universal character name specifying a short identifier of 00FFFF or less is considered 6 characters, each universal character name specifying a short identifier of 010000 or more is considered 10 characters, and each extended source character is considered the same number of characters as the corresponding universal character name, if any)
- 4095 external identifiers in one translation unit
- 511 identifiers with block scope declared in one block
- 4095 macro identifiers simultaneously defined in one preprocessing translation unit
- 127 parameters in one function definition
- 127 arguments in one function call
- 127 parameters in one macro definition
- 127 arguments in one macro invocation
- 4095 characters in a logical source line
- 4095 characters in a string literal (after concatenation)
- 32767 bytes in an object (in a hosted environment only)
- 15 nesting levels for
#included files- 1023
caselabels for aswitchstatement (excluding those for any nestedswitchstatements)- 1023 members in a single structure or union
- 1023 enumeration constants in a single enumeration
- 63 levels of nested structure or union definitions in a single member declaration list
(C23 5.3.5.2 "Translation limits" paragraph 1.)
Must a conforming hosted implementation accept all strictly conforming programs, including those that reach all of these limits at the same time? Note that the C99 Rationale says the following:
The requirement that a conforming implementation be able to translate and execute at least one program that reaches each of the stated limits is not meant to excuse the implementation from doing the best it can to translate and execute other programs. It was deemed infeasible to require successful translation and execution of all programs not exceeding those limits. Many of these limits require resources such as memory that a reasonable implementation might allocate from a shared pool; so there is no requirement that all the limits be attained simultaneously. Requiring just one acceptable program that attains each limit is simply meant to ensure conformance with these requirements.
(Section 5.2.4.1 "Translation limits" paragraph 4 C99 Rationale.)
Which suggests not, but the wording appears to require it if "shall not exceed any minimum implementation limit" is interpreted as referring to the limits described in "Translation limits". All of the following questions assume that "any minimum implementation limit" does refer to the limits described in "Translation limits", since it is not clear what the meaning could be otherwise. Note that several sections have portions labeled "Implementation limits" which refer to "Translation limits".
How are levels of nesting counted? Consider the following:
int main(){{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
This has exactly one hundred twenty eight sets of braces. Does that count as one hundred twenty seven levels of nesting because there are one hundred twenty seven sets of braces surrounding the innermost set of braces, or does it count as one hundred twenty eight levels of nesting by including the innermost set of braces as well?
How do standard headers interact with these translation limits? For example, suppose a standard header is included at a point where headers can be included but those headers cannot include any further headers without exceeding the minimum implementation limits. Would including the standard header at that point possibly exceed the minimum implementation limits? If it would, then how many nested inclusions can standard headers perform?
How do standard library macros interact with these translation units? For example, suppose a standard library macro is expanded at a point where no parenthesized expressions can be used without exceeding the minimum implementation limits. Would expanding the standard library macro at that point possibly exceed the minimum implementation limits? If it would, then how many nested parenthesized expressions, nested parenthesized declarators, nested structure definitions, and nested union definitions can be used by standard library macros?
The following can be nested infinitely, but there does not seem to be any minimum implementation limits:
sizeof expressions that use parenthesized type names,alignof expressions,_BitInt type specifiers,__has_embed expressions,__has_embed parameter pp-balanced-tokens, andSome of these cannot be directly nested but require other constructs
to nest, for example _BitInt((_BitInt(3))2). Note that selection
statements and iteration statements create blocks so they are already
covered by the existing wording. The following can be repeated
infinitely without nesting multiple times, but there does not seem to
be any minimum implementation limits:
_Atomic,Whitespace (including comments) can be of infinite length and done infinite times, but is intentionally omitted because it is easy for implementations to skip. Was it intended for there to be some restrictions on these? No implementations are actually capable of accepting programs of unbounded length. Perhaps there should also be limits on the complexity that macros can achieve.
Does "511 identifiers with block scope declared in one block" include
the implicitly defined __func__?
Does "4095 macro identifiers simultaneously defined in one
preprocessing translation unit" include the implicitly defined macros
such as __STDC__ or macros defined in standard headers? Moreover,
does it include implementation specific predefined macros that use
reserved identifiers or implementation specific macros defined in
standard headers that use reserved identifiers or one of the reserved
prefixes?
Does "4095 external identifiers in one translation unit" include identifiers declared in standard headers with external linkage? Moreover, does it include implementation specific identifiers declared in standard headers with external linkage?
Does "12 pointer, array, and function declarators (in any
combinations) modifying an arithmetic, structure, union, or void type
in a declaration" mean to include nullptr_t? Also:
As discussed in 5.3.5.2, an implementation may limit the number of pointer, array, and function declarators that modify an arithmetic, structure, union, or
voidtype, either directly or via one or moretypedefs.
(C23 6.7.7.1 "General" paragraph 7.)
Here it is suggested that this applies to any construction of a type,
but it seems clearly limited to declarations and there is no mention
of typedefs.