25

I'm checking the standard about narrowing conversion, and I think for a narrowing conversion an error should be triggered. Because the standard says:

[ Note: As indicated above, such conversions are not allowed at the top level in list-initializations. — end note ]

I think the description of "not allowed" means the compiling should fail.

But someone told me that here just says "the program is ill-formed", and the standard won't require that compilation must fail.

if a narrowing conversion (see below) is required to convert the element to T, the program is ill-formed.

So my question is: Does the standard specify whether an error or warning should be generated? Or for some cases the compiling should fail? From the aspect of a compiler, is it OK to make the program compile and just give some warnings?

BTW: Clang 4.0.0 and Gcc 7.0.0 behave differently.

float a {1.e39}; // Error for both Clang and GCC
double d;
float a3{d};     // Error for Clang, warning for GCC
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • 1
    Related question: [Why doesn't narrowing conversion used with curly-brace-delimited initializer cause an error?](http://stackoverflow.com/a/31685448/1708801) which also discussed that ill-formed only requires a diagnostic which could be an error or a warning. – Shafik Yaghmour Nov 26 '16 at 21:06

5 Answers5

31

The standard doesn't use the terms "error" and "warning", it only talks about cases where the compiler must "issue a diagnostic".

In your example, if the program is "ill-formed", the compiler is required to tell you that somehow - issue a diagnostic.

After that, it can do anything it likes - including compiling and running the program anyway. The standard only specifies what happens for conforming code, everything else is undefined. And then, as we know, anything can happen.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
  • So standard never specify an error should be triggered, or compiling should fail, even with the description like "not allowed". All is just implementation-specific behavior. – songyuanyao Nov 25 '16 at 15:03
  • 8
    If you do something that is not allowed, the compiler must tell you so. The standard doesn't mandate a specific form for the message, or what happens afterwards, if anything. – Bo Persson Nov 25 '16 at 15:17
  • 2
    It's also worth mentioning that many compilers only claim to be fully conforming implementations when used in a specific, non-default mode. This gives them leeway to not issue diagnostics in the default mode even for cases where the standard mandates a diagnostic. – zwol Nov 25 '16 at 18:58
16

The only requirement for an ill-formed program is that the compiler must "issue a diagnostic", where "diagnostic" has an implementation-defined meaning. Having done that, the compiler is free to continue to compile the code. That's the main hook for implementation-specific behavior.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165
5

If a program not is ill-formed, the compiler must produce executable output. If the program contains no UB, the executable must behave as the abstract machine the standard describes states it will behave. If it does contain UB, the executable can do anything.

If the program is ill-formed with no diagnostic required, the compiler can do anything. It can produce an executable output, or not. That executable output can do anything at all. It could design a program that seems to match the intent of the code, for example.

Compilers are free to print diagnostics whenever they want.

Compilers are mandated to print diagnostics in some situations. "Most" ill-formed programs require a diagnostic. What a diagnostic is exactly is implementation defined. It has been noted that printing a single blank newline, or a space, is a valid diagnostic under the standard.

That would be considered a poor quality of implementation.

Once the diagnostic is printed when there is an ill-formed program that requires a diagnostic, the compiler is free to do anything. It can produce an executable that somewhat matches what you ask for, produce an executable that does anything it wants, or produce no executable.

The standard does not differentiate between warnings and errors.

An ill-formed program that requires a diagnostic that print a warning, then continue to compile, does not violate the standard.

An ill-formed program that requires a diagnostic that prints an error, then doesn't continue to compile, does not violate the standard.

An ill-formed program with no diagnistic required can print a diagnostic. It may choose to produce an executable or not. The executable could do something reasonable or not.

A well formed program can have the compiler issuing a diagnostic. This diagnostic could be described as a warning. It could also be described as an error, but the compiler must produce an executable, and the executable must do what the standard mandates.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
2

If a program is not ill-formed (and has no UB), the compiler has to produce an executable output. If a program is ill-formed, the standard poses no restriction on whether or not there is an output.

If a program is ill-formed, and that is not NDR, a diagnostic must be produced. The standard does not differentiate between warnings or errors.

sp2danny
  • 7,488
  • 3
  • 31
  • 53
  • I believe that a compiler may also skip creating an executable if its execution would necessarily (i.e. regardless of input) cause Undefined Behavior, even if the program is well-formed. E.g. `int main() { int a = 0; return 1/a;}` is well-formed. – MSalters Nov 25 '16 at 14:58
  • The compiler doesn't necessarily have to produce an *"executable"* output. – Nawaz Nov 25 '16 at 15:08
  • 1
    Someone unfamiliar with _diagnostic_ is probably also unfamiliar with _NDR_. Consider expanding it. – Jeffrey Bosboom Nov 25 '16 at 21:10
2

Notes in the standard are non-normative and do not affect the definition of the language. So the note in your first quotation is not important from a language lawyer perspective.

Having said that, I think that both of your quotations mean the same thing. An "ill formed program" is one that is not constructed according to the syntax rules, diagnosable semantic rules, and one definition rule, of the standard (emphasis mine). If a certain semantic is "not allowed", that just means it violates a diagnosable semantic rule of the langugae, and therefore just means it is ill formed.

The compiler is required to issue a diagnostic for a program that is ill formed. After that, the compiler can do anything it wants. The standard does not specify any conditions under which compilation must fail.

Oktalist
  • 14,336
  • 3
  • 43
  • 63
  • Where did you get the quote about `#error`, I found [here](http://eel.is/c++draft/cpp.error#1) also just says "causes the implementation to produce a diagnostic message that includes the specified sequence of preprocessing tokens, and renders the program ill-formed." So compiling doesn't have to fail either.. – songyuanyao Nov 25 '16 at 15:16
  • Thanks, fixed. I couldn't find the `#error` in the C++ standard so assumed it was imported by reference to the C standard which uses the wording about "shall not successfully translate". – Oktalist Nov 25 '16 at 15:18