9
votes

I have some trouble understanding semantics of 5.1.1.3/1 Diagnostics subclause from N1570 C11 draft (emphasis mine):

A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. Diagnostic messages need not be produced in other circumstances.9

I understand that the intent was to exclude (non-constraint) undefined behavior (thus that are no diagnostics on e.g. buffer overflow), but what about #error directive? As in 6.10.5/1 Error directive:

A preprocessing directive of the form

# error pp-tokensopt new-line

causes the implementation to produce a diagnostic message that includes the specified sequence of preprocessing tokens.

Does these both subclauses are not mutually exclusive?

For some other reference see also DR#176.

2
I suppose the intent was that #error should always produce a diagnostic message, but this wasn't mentioned in the former clause. - Drew McGowen
IIRC Keith Thompson said that the error directive was the only place where an implementation is required to produce a diagnostic. - user3920237
"need not be produced" does not mean "cannot be produced". - Hans Passant
@remyabel: I would argue to this point as "shall produce" (5.1.1.3/1) means that "conforming implementation is required to" and this subclause is normative. - Grzegorz Szpetkowski
@GrzegorzSzpetkowski Precisely, "shall" actually means "must" in this context - kdopen

2 Answers

4
votes

C99 went a step further than the suggested resolution for that DR. Instead of requiring a diagnostic, they require treating it as an error.

4. Conformance

4 The implementation shall not successfully translate a preprocessing translation unit containing a #error preprocessing directive unless it is part of a group skipped by conditional inclusion.

Now, strictly speaking, perhaps you're right that an implementation could choose to refuse to compile a program containing an #error directive without issuing a diagnostic, claiming that 5.1.1.3 allows it to ignore the semantics for #error. However, an implementation that goes to such lengths to being as useless as possible within the bounds set by the standard, would easily work around any attempt to require a diagnostic: the implementation could simply dump the complete preprocessor output (including anything following #error), and follow that by "there's an error in there somewhere". Because of that, it effectively doesn't matter whether the standard requires a diagnostic. There's no excuse for an implementation not to do so, and very little that the standard could to do force unwilling implementors.

4
votes

As someone who served on the committee, our response to a question like this would often begin with a phrase along the lines of "A careful reading of the standard ...", which is not quite as glib as it sounds. the language used is very specific. Consider the first clause

A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. Diagnostic messages need not be produced in other circumstances.9

This clause is explicitly referring to a "violation of any syntax rule or constraint". A well formed #error directive does not, therefore, trigger this clause. Thus it does not apply, and mutual-exclusion is moot.

Also note the final sentence, where it says that diagnostics " need not be produced ". The term "need not" does not imply "must not". It simply means the implementation has the option whether or not to issue a diagnostic for other conditions (for example, style concerns). But again this entire clause is irrelevant for #error

Your second quote simply states exactly what an implementation must do for a well-formed #error directive.