Created on 2024-09-05.00:00:00 last changed 2 months ago
Proposed resolution:
This wording is relative to N4986.
Modify [macro.names] as indicated:
-1- A translation unit that includes a standard library header shall not `#define` or `#undef` names declared in any standard library header.
-2- A translation unit that includes a standard library header shall not `#define` or `#undef` names lexically identical to keywords, to the identifiers listed in Table 4, or to the attribute-tokens described in [dcl.attr], except that the names `likely` and `unlikely` may be defined as function-like macros ([cpp.replace]).
Issue 294 changed [macro.names] from:
A translation unit that includes a header shall not contain any macros that define names declared or defined in that header. Nor shall such a translation unit define macros for names lexically identical to keywords.to:
A translation unit that includes a standard library header shall not `#define` or `#undef` names declared in any standard library header.A translation unit shall not `#define` or `#undef` names lexically identical to keywords.
Note that the second sentence of the original says "such a translation unit" when prohibiting things like `#define while`. This means the prohibition only applies to "a translation unit that includes a header". The replacement has the prohibition in a separate paragraph and does not clearly say that it only applies when a header is included.
The issue discussion seems clear that the concern is about C++ headers including other unspecified headers, which is allowed in C++ (though not in C). There is no justification for broadening the second sentence to apply unconditionally. Such a rule would belong in [cpp] anyway, not in library wording. That overreach doesn't appear to have been intended, and we should clarify what the library is prohibiting.
It was pointed out on the reflector that it's not enough to only prohibit
defining such macros after including headers, because in some cases
that could still break the library header. For example, the library macro
`assert` typically uses `void` and so `#define void ...` would break `assert`
even if it happens after including <cassert>
.
History | |||
---|---|---|---|
Date | User | Action | Args |
2024-09-05 10:26:53 | admin | set | messages: + msg14357 |
2024-09-05 00:00:00 | admin | create |