Are Notes and Examples in the Core Language Specification of the C++ Standard Non-Normative

Are notes and examples in the core language specification of the C++ Standard non-normative?

See §6.5 of the ISO/IEC Directives Part 2. Notes, examples, and footnotes are all considered "informational", as opposed to "normative".

For notes and examples:

Notes and examples integrated in the text of a document shall only be used for giving
additional information intended to assist the understanding or use of the document. They shall
not contain requirements ("shall"; see 3.3.1 and Table H.1) or any information considered
indispensable for the use of the document, e.g. instructions (imperative; see Table H.1),
recommendations ("should"; see 3.3.2 and Table H.2) or permission ("may"; see Table H.3).
Notes may be written as a statement of fact.

For footnotes:

Footnotes to the text give additional information; their use shall be kept to a minimum. As is
the case for notes and examples integrated in the text (see 6.5.1) footnotes shall not contain
requirements or any information considered indispensable for the use of the document.

However, note that footnotes to figures and tables can contain requirements.

Is something undefined behavior by omission?

However, how can the standard say something is undefined behavior without explicitly saying so?

Because that's what undefined means. What happens has not been defined. The standard defines what is expected of a valid program, it doesn't attempt to list every conceivable invalid program and say "this is undefined, also this is undefined, also this is undefined".

The standard doesn't specify what happens if you set fire to your computer while the program is running. That doesn't mean it's well-defined. It's clearly undefined.

Literally anything can happen in a program and it is assumed that it is not undefined behavior unless said so by the standard.

I'm not sure what you're trying to say here, but it sounds 180° backwards.

Does this mean a non-standard program is undefined behavior by default?

What is a "non-standard program"?

C11 related language correctness

The example comes from Example 3 in §6.5.2.3 Structure and union members of ISO/IEC 9899:2011. One of the prior paragraphs is (emphasis added):

¶6 One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the completed type of the union is visible. Two structures share a common initial sequence if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members.

The code quoted in the question is preceded by the comment:

The following is not a valid fragment (because the union type is not visible within function f).

This now makes sense in light of the highlighted statement. The code in g() is making use of the common initial sequence, but that only applies where the union is visible and it isn't visible in f().

The issue is also one of strict aliasing. That's a complex topic. See What is the strict aliasing rule? for the details.

For whatever it is worth, GCC 7.1.0 doesn't report the problem even under stringent warning options. Neither does Clang, even with the -Weverything option:

clang -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
-Wstrict-prototypes -Weverything -pedantic …

Is support of Annex K in C11 required for a conforming implementation?

Annex K is optional; it says so itself.

See K.2 paragraph 2:

An implementation that defines __STDC_LIB_EXT1__ shall conform to the
specifications in this annex.

with a footnote:

Implementations that do not define __STDC_LIB_EXT1__ are not required to conform to these
specifications.

And paragraph 3 says:

Subclause K.3 should be read as if it were merged into the parallel
structure of named subclauses of clause 7.

which is why it's not necessary to mention it in the library section, clause 7 (or at least the authors of the standard didn't feel it was necessary).

An implementation that defines __STDC_LIB_EXT1__ must define it as 201112L; both N1570 and the released C11 standard got this wrong, but it was fixed in a Technical Corrigendum.

Clarification on an example of unions in C11 standard

It matters because of 6.5.2.3 paragraph 6 (emphasis added):

One special guarantee is made in order to simplify the use of unions:
if a union contains several structures that share a common initial
sequence (see below), and if the union object currently contains one
of these structures, it is permitted to inspect the common initial
part of any of them anywhere that a declaration of the completed type
of the union is visible
. Two structures share a common initial
sequence
if corresponding members have compatible types (and, for
bit-fields, the same widths) for a sequence of one or more initial
members.

It's not an error that requires a diagnostic (a syntax error or constraint violation), but the behavior is undefined because the m members of the struct t1 and struct t2 objects occupy the same storage, but because struct t1 and struct t2 are different types the compiler is permitted to assume that they don't -- specifically that changes to p1->m won't affect the value of p2->m. The compiler could, for example, save the value of p1->m in a register on first access, and then not reload it from memory on the second access.

In C++, does initializing a global variable with itself have undefined behaviour?

Surprisingly, this is not undefined behavior.

Static initialization [basic.start.static]

Constant initialization is performed if a variable or temporary object
with static or thread storage duration is constant-initialized. If
constant initialization is not performed, a variable with static
storage duration or thread storage duration is zero-initialized
.
Together, zero-initialization and constant initialization are called
static initialization; all other initialization is dynamic
initialization. All static initialization strongly happens before any
dynamic initialization
.

Important parts bold-faced. "Static initialization" includes global variable initialization, "static storage duration" includes global variables, and the above clause is applicable here:

int i = i;

This is not constant-initialization. Therefore, zero-initialization is done according to the above clause (for basic integer types zero-initialization means, unsurprising, that it's set to 0). The above clause also specifies that zero initialization must take place before dynamic initialization.

So, what happens here:

  1. i is initialized to 0.
  2. i is then dynamically initialized, from itself, so it still remains 0.

C++11 Accessing Unscoped Enumerators with Qualified Name

The quote you are looking for from the draft C++11 standard is from section 5.1 Primary expressions which in paragraph 10 says:

A nested-name-specifier that denotes an enumeration (7.2), followed by
the name of an enumerator of that enumeration, is a qualified-id that
refers to the enumerator. The result is the enumerator. The type of
the result is the type of the enumeration. The result is a prvalue.

It does not restrict the use to scoped enumerations and so the example in section 7.2 Enumeration declarations:

enum direction { left='l', right='r' };

void g() {
direction d; // OK
d = left; // OK
d = direction::right; // OK
}

is entirely consistent. This is also consistent with section 3.4.3 Qualified name lookup which says:

The name of a class or namespace member or enumerator can be referred
to after the :: scope resolution operator (5.1) applied to a
nested-name-specifier that denotes its class, namespace, or
enumeration. [...]

and:

A name prefixed by a nested-name-specifier that nominates an
enumeration type shall represent an enumerator of that enumeration.

again, there is nothing restricting this behavior to scoped enumerations.

Examples are non normative but as long as they don't conflict with the normative text then they should be considered a good guideline.



Related Topics



Leave a reply



Submit