21

For example, the famous words (§3.2/1)

No translation unit shall contain more than one definition of any variable, function, class type, enumeration type, or template.

I believe "shall" requirements are to be interpreted as though they are implicitly followed by "otherwise the program is ill-formed" unless otherwise specified. However, others claim that "shall" instead means "otherwise the behavior is undefined".

In every case I've come across in the standard in which a "shall" requirement was not followed by something like "otherwise the behavior is undefined" or "no diagnostic required", the rule it occurred in was one that is obviously diagnosable and is diagnosed by all compilers I know of (the above paragraph being an example). That's why I believe it means "otherwise the program is ill-formed", i.e., a diagnostic is required.

Anyway, those are just my thoughts. I'd appreciate an authoritative answer.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • This text comes from The One Definition Rule, which is a special case! See [defns.well.formed] which says that any violation of "shall" in the ODR means the program is ill-formed. – M.M Aug 14 '14 at 11:09

2 Answers2

16

Yes, to be well-formed, the program must follow the One Definition Rule that you've quoted in the question (§1.3.26):

well-formed program

C++ program constructed according to the syntax rules, diagnosable semantic rules, and the One Definition Rule (3.2).

The other diagnosable rules are specified as (§1.4):

1.4 Implementation compliance [intro.compliance]

1 The set of diagnosable rules consists of all syntactic and semantic rules in this International Standard except for those rules containing an explicit notation that “no diagnostic is required” or which are described as resulting in “undefined behavior.”
2 Although this International Standard states only requirements on C++ implementations, those requirements are often easier to understand if they are phrased as requirements on programs, parts of programs, or execution of programs. Such requirements have the following meaning:
— If a program contains no violations of the rules in this International Standard, a conforming implementation shall, within its resource limits, accept and correctly execute2 that program.
If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this Standard as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message.
— If a program contains a violation of a rule for which no diagnostic is required, this International Standard places no requirement on implementations with respect to that program.
[emphasis added]

And yes, as noted in the second bullet point, if a diagnosable rule is violated, a diagnostic is required.

quantdev
  • 23,517
  • 5
  • 55
  • 88
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • OK, let me see if I understand you correctly: "Shall" has no special meaning; it's just the language used in some of the rules. If a program violates *any* rule, it's ill-formed, unless it says "undefined behavior" explicitly. And if a program is ill-formed, an implementation must issue a diagnostic, unless the rule explicitly says "no diagnostic required". – Brian Bi Aug 14 '14 at 05:32
  • 1
    @Brian: Not exactly. In this respect, it doesn't differentiate between "undefined behavior" and "no diagnostic required." So, unless it says one of those two things, breaking a rule requires a diagnostic. For what it's worth, the C standard is a little more explicit about requiring "shall" for a rule to qualify as a requirement. The same was suggested to Pete Becker (then editor of the C++ standard) but he apparently didn't like the idea of restricting diagnosable rules to those containing "shall" or "shall not". I can't blame him much--it can lead to very stilted phrasing in some cases. – Jerry Coffin Aug 14 '14 at 05:37
  • I am not a native English speaker but wouldn't be clearer with "must" instead of "shall" ? – AndersK Aug 14 '14 at 10:15
  • @Claptrap the footnote to table H.1 quoted in my answer states: "Do not use “must” as an alternative for “shall”. (This will avoid any confusion between the requirements of a document and external statutory obligations.)" – TemplateRex Aug 14 '14 at 10:17
6

In addition to @JerryCoffin's answer, there is also ISO/IEC Directives Part 2 (that governs all ISO/IEC documents, including the C++ Standard), in particular Annex H Verbal forms for the expression of provisions

The verbal forms shown in Table H.1 shall be used to indicate requirements strictly to be followed in order to conform to the document and from which no deviation is permitted.

shall:

  • is to,
  • is required to,
  • it is required that,
  • has to,
  • only … is permitted,
  • it is necessary

shall not:

  • is not allowed [permitted] [acceptable] [permissible],
  • is required to be not
  • is required that … be not
  • is not to be

So a violation of a "shall" requirement makes a program ill-formed. The diagnostic issues have been answered elsewhere.

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
  • @hvd fixed, I had some connnection troubles – TemplateRex Aug 14 '14 at 10:15
  • Ah, that explains that. :) I think this shows that a program that violates a "shall" requirement does not conform to the C++ standard, but this doesn't show that such a program is ill-formed: it could equally be undefined, could it not? –  Aug 14 '14 at 12:20
  • @hvd I'm not sure, but I think "undefined behavior" is a subset of "ill-formed". See `[defns.undefined]`: "Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed." It would be interesting if you could find a requirement, that when erroneously used implies undefined behavior. – TemplateRex Aug 14 '14 at 14:21
  • Well, ill-formed requires a diagnostic unless a diagnostic is explicitly not required, undefined behaviour implicitly does not require a diagnostic, so the latter cannot be a subset of the former. A concrete "shall" requirement that does not require a diagnostic is 17.6.2.2p3: "A translation unit shall include a header only outside of any external declaration or definition, and shall include the header lexically before the first reference in that translation unit to any of the entities declared in that header." A diagnostic would be unreasonable: [...] –  Aug 14 '14 at 14:38
  • [...] such a diagnostic would prohibit header guards, because the rule prohibits even `#include ` / `void f() {` / `#include ` / `}`, and pretty much every implementation there is will make the second inclusion have absolutely no effect. –  Aug 14 '14 at 14:38
  • @user743382 that sure is an unreasonable rule you found there :-) In order to enforce that, the compiler would have to be cognizant of the parse syntax and semantics during the stage in which the #defines are being processed, which is usually considered to be a logically and functionally distinct "preprocessing" stage. The rule apparently also disallows a lot of techniques I've seen in which #included files consist of code fragments intended to be #included inside function bodies. I wonder if compiler writers have simply taken the attitude "this is absurd, I'm going to pretend I didn't see it" – Don Hatch Jun 13 '23 at 03:19