Name
n3906, alx-0065r7 - Refactor non-directives
Category
Cosmetic refactor; readability; slaying an Earthly Demon
Authors
Alejandro Colomar <alx@kernel.org>
Jens Gustedt <jens.gustedt@inria.fr>
History
<https://www.alejandro-colomar.es/src/alx/alx/wg14/alx-0065.git/>
r0 (2025-04-20):
- Initial draft.
r1 (2025-04-20):
- Fix typos.
- Move back non-directive to under 'group'.
- Define the term standard directive name.
r2 (2025-06-29):
- s/Description/Rationale/
- Remove obsolete paragraph from Rationale.
- Move non-directive above text-line in group-part, since it
has preference.
- s/anything/any line/ in 6.10.1p2. # is not a directive in
the middle of a line: it's either a syntax error or the
stringify operator.
- Use 6.10.9+1 to refer to the new subsection after 6.10.9.
- Reorder this proposal with respect to alx-0013. This one
should be applied first.
r3 (2025-07-01; n3632):
- Fix interaction with other proposals.
- Use = instead of * for moved lines.
r4 (2025-08-29):
- Split some changes into separate papers.
- Add missing endif in standard directive names.
r5 (2025-08-29):
- Split from alx-0014.
- ffix
r6 (2026-04-06):
- Refer to n3854 (nothing changed).
- Add comment about Earthly Demon.
- Append to category: 'slaying an Earhtly Demon'.
r7 (2026-06-03; n3906):
- Say identifier *preprocessing* token. [Joseph]
Principles
- Keep the language small and simple
- Avoid ambiguities
Rationale
The specification of preprocessing directives is a bit messy.
The syntax is largely ad-hoc, and there are patterns that could
we could make to simplify the syntax of directives, allowing us
to split the huge syntax paragraph into smaller ones for each
subsection.
This proposal is not definitive, and I believe some further
changes can be good, but this is a self-contained net
improvement that will allow further refactors in this space,
and by being smaller, it should be easier to reason about.
I'll propose further improvements once we merge this. That will
also reduce conflicts with other proposals.
Interaction with other proposals
This proposal depends on alx-0014[A-H].
This blocks alx-0003 ("Add directives #def and #enddef").
This blocks alx-0013 ("Prohibit non-directives (other than ID directives)").
Proposed wording
Based on N3854.
6.10.1 Preprocessing directives :: General
@@ Syntax, p1
group-part:
if-section
control-line
+ non-directive
text-line
- <b>#</b> non-directive
...
-non-directive:
- pp-tokens new-line
@@ Description, p2
-A <i>preprocessing directive</i>
-consists of a
+Any
sequence of preprocessing tokens
-that satisfies the following constraints:
+that satisfies the following constraints
+is a <i>preprocessing directive</i>:
...
+That is,
+a directive is any line of the form
+
+ <b>#</b> pp-tokens(opt) new-line
## The reword of the paragraph above allows us to remove the
## first sentence of p3, because now we've made it impossible to
## start a text line with a '#', since it now is by definition a
## directive.
@@ New p after p2
+A standard directive
+is a preprocessing directive where
+either the list of preprocessing tokens is empty (see 6.10.9)
+or the first preprocessing token
+is an identifier preprocessing token
+that is one of the standard directive names.
+
+ define elif elifdef elifndef
+ else embed endif error
+ if ifdef ifndef include
+ line pragma undef warning
## This new paragraph will allow a clearer rewrite of the second
## sentence of p3.
@@ p3
-A text line
-shall not begin with a <b>#</b> preprocessing token.
-A non-directive shall not begin with
-any of the directive names appearing in the syntax.
## The second sentence is replaced by 6.10.9+1p2 (see below).
## The first sentence is an Earthly Demon slayed.
@@ p7
When in a group that is skipped (6.10.2),
the directive syntax is relaxed
to allow any sequence of preprocessing tokens
to occur between
-the directive name
+a directive name
and the following new-line character.
## In some cases, there's not a directive name (think of
## non-directives).
6.10 Preprocessing directives
@@ New subsection after 6.10.9
+6.10.<9+1> Non-directive
+Syntax
+1
+ non-directive:
+ <b>#</b> pp-tokens new-line
+
+Description
+2
+ The first token in a non-directive
+ is none of the standard directive names.
+
+Semantics
+3
+ Execution of a non-directive preprocessing directive
+ results in undefined behavior.
## alx-0013 will replace this p3 by implementation-defined
## behavior for supported extensions, and a constraint for
## others. non-directive will then be renamed to
## extended-directive.