Why is calling the main function supposedly undefined behavior (UB) - c++

I fear this is again a question about interpreting the ISO/IEC 14882 (the C++ standard) but:
Is calling main from the program e.g. my calling main() recursively from main not at least implementation defined behavior? (Update: I imply later ill-formed not implementation defined, also not UB, see below and answer)
6.9.3.1 [basic.start.main] states
3 The function main shall not be used within a program. The linkage (6.6) of main is implementation-defined...
The consensus seems to be undefined behavior (UB). The documentation of MSVC also points towards UB, the one of gcc also implicitly denies implementation-defined behavior. It can not be [defns.unspecified] unspecified behavior since I would interpret shall not as ill-formed.
However, despite the implementations, to my interpretation is should not be UB but as 4.1 [intro.compliance] states
1 The set of diagnosable rules consists of all syntactic and semantic rules in this document except for those
rules containing an explicit notation that “no diagnostic is required” or which are described as resulting in
“undefined behavior”.
...
(2.2) — If a program contains a violation of any diagnosable rule or an occurrence of a construct described in
this document as “conditionally-supported” when the implementation does not support that construct,
a conforming implementation shall issue at least one diagnostic message.
For me the reasoning seems clear
tl;dr
calling main implies the program contains a violation of the rule of [basic.start.main]
[basic.start.main] does not state calling/use is UB or a diagnostic is not required
is an element of "diagnosable rules" as per [intro.compliance]
[intro.compliance] 2.2 states violation of any diagnoseable rule must be issued at least one diagnostic message
Since 3. and 4. the usage of main shall issue at least one diagnostic message
Since 5. 1. is not UB
Since neither gcc,MSVC or clang issue an error or warning but compile, all major implementations are not compliant
Of course since 7. I feel again in the Don Quixote scenario i.e. being wrong, so I would appreciate if someone could enlighten me about my mistake. Otherwise, there are standard defects, aren't there?

I think your analysis is correct: calls to main are ill-formed.
You have to pass the -pedantic flag to make GCC and Clang conform. In that case, Clang says
warning: ISO C++ does not allow 'main' to be used by a program [-Wmain]
and GCC says
warning: ISO C++ forbids taking address of function '::main' [-Wpedantic]
But they allow calls to main as an extension. The standard permits such an extension, since it doesn't change the meaning of any conforming programs.

Related

Do "mandates" conditions in the C++ standard always result in an error? [duplicate]

C++03 Standard defines well-formed program (1.3.14 [defns.well.formed]) as
a C++ program constructed according to the syntax rules, diagnosable semantic rules, and the One Definition Rule (3.2)
It further defines an ill-formed program (1.3.4 [defns.ill.formed]) as
input to a C++ implementation that is not a well-formed program (1.3.14)
and the Standard is full of statements such as "if X then the program is ill-formed" for example (2.13.1/3):
A program is ill-formed if one of its translation units contains an integer literal that cannot be represented by any of the allowed types.
Yet I haven't found what the C++ implementation is required to do with ill-formed programs.
Suppose I have an ill-formed program. Now what?
Is the C++ implementation required to do something specific when it encounters an ill-formed program or is the C++ implementation behavior just undefined?
Is the C++ implementation required to do something specific when it encounters an ill-formed program or is the C++ implementation behavior just undefined?
If the Standard does not specify otherwise, an implementation should emit a diagnostic message (error or warning). However, for some violations the Standard explicitly specifies that no diagnostic is required. In this case, the program is ill-formed, but implementations are not required to tell the user - usually, because doing so in the general case would be too difficult.
Concerning the One Definition Rule, for example, see Paragraph 3.2/4 of the C++11 Standard:
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used
in that program; no diagnostic required.
Regarding the requirements on implementations when encountering a violation of a rule, Paragraph 1.4/2 specifies:
[...]
— If a program contains no violations of the rules in this International Standard, a conforming implementation
shall, within its resource limits, accept and correctly execute 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.
Also relevant is Paragraph 1.4/1, which explains what is meant by "diagnosable rules" in the Paragraph quoted above:
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.”
So to sum it up: if an ill-formed program contains a diagnosable violation for which the Standard does not explicitly specify "no diagnostic required", conforming implementations should emit a diagnostic.
Quoting [intro.compliance]§2:
If a program contains no violations of the rules in this International Standard, a conforming implementation shall, within its
resource limits, accept and correctly execute 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.
I haven't found any other relevant passages in the standard. If we combine this with [defns.undefined]:
undefined behavior
behavior for which this International Standard imposes no requirements
[ Note: Undefined behavior may be expected when this International
Standard omits any explicit definition of behavior or when a program
uses an erroneous construct or erroneous data. Permissible undefined
behavior ranges from ignoring the situation completely with
unpredictable results, to behaving during translation or program
execution in a documented manner characteristic of the environment
(with or without the issuance of a diagnostic message), to terminating
a translation or execution (with the issuance of a diagnostic
message). Many erroneous program constructs do not engender undefined
behavior; they are required to be diagnosed. -end note ]
I'd say we arrive at "issue a diagnostic message and further the behaviour is undefined," because the standard doesn't say anything more about it.
(First of all, sorry for my English)
The Standard, in §1.4.2 says:
If a program contains a violation of any diagnosable rule [...] a conforming implementation shall issue at least one diagnostic message.
The definition of a ill-formed program is "a program that is not well formed" (§1.3.9), and a well-formed program is (§1.3.26):
C++ program constructed according to the syntax rules, diagnosable semantic rules, and the One Definition Rule
So, a ill-formed program does implicitly violate "some" rule. If a rule R has the following structure:
If a program has property P, it is an ill-formed program.
When a program has such property P, it does implicitly violate a rule (by definition of an ill-formed program), although it isn't clear which rule is the one which are being violated, since R itself doesn't (from a strictly logical point of view).
The only relevant quote I could find says that an implementation is required to diagnose an ill-formed program, but it can finish compiling it:
1.4 Implementation compliance [intro.compliance]
8) A conforming implementation may have extensions (including additional
library functions), provided they do not alter the behavior of any
well-formed program. Implementations are required to diagnose programs
that use such extensions that are ill-formed according to this
International Standard. Having done so, however, they can compile and
execute such programs.

Which guarantees does the C++ standard have when it comes to issuing diagnostic messages?

While reading the C++ standard, one often sees designations like "... ill-formed, no diagnostic required". A (random) example can be found in 13.8.1/17:
The class S1::Inner1 is ill-formed, no diagnostic required, because
it has no valid specializations.
Where can one find an opposite normative language in the standard, which would prescribe a diagnostic for an ill-formed program?
What you are looking for is [intro.compliance]/1
The set of diagnosable rules consists of all syntactic and semantic rules in this document except for those rules containing an explicit notation that “no diagnostic is required” or which are described as resulting in “undefined behavior”.
It is then followed up with [intro.compliance]/2
If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this document as “conditionally-supported” when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message.
which guarantees that if you break one of the diagnosable rules you'll get a diagnostic message.

Is it standard-compliant to compile ill-formed program in success?

For an ill-formed C++ program like:
foo^##$bar%$
Is it standard-compliant for compiler to yield compiled binary with diagnostic message, rather than interrupting the compilation as g++/clang++ do?
intro.compliance states that:
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.
which does not require compilation error in this case.
Possibly related:
What is the C++ compiler required to do with ill-formed programs according to the Standard?
Ill-Formed, No Diagnostic Required (NDR): ConstExpr Function Throw in C++14
Yes, it is legal for the implementation to produce a binary when the input is an ill-formed program. Here is [intro.compliance]/8 in C++14:
A conforming implementation may have extensions (including additional library functions), provided they do
not alter the behavior of any well-formed program. Implementations are required to diagnose programs that
use such extensions that are ill-formed according to this International Standard. Having done so, however,
they can compile and execute such programs.
In such cases the diagnostic would usually be referred to as a "warning" (as opposed to "error").

In the C++ standard, what is specified to occur when a "shall" requirement is violated?

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.
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.
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.

Why does my C++ compiler allow recursive calls to main? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is it legal to recurse into main() in C++?
#include <iostream>
using namespace std;
int main() {
static int var = 5;
std::cout << --var;
if(var)
main();
}
gcc compiles the code http://ideone.com/lIp3A . I know that main cannot be used inside main in C++. How come this code compiles?
The code is ill-formed because it violates the shall construct of §3.6.1.3
§3.6.1.3 says :
The function main shall not be used within a program.
The shall construct
A diagnosable rule is defined as (§1.4.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.”
§3.6.1.3 defines a diagnosable rule.
According to §1.4.2:
— If a program contains no violations of the rules in this International Standard, a conforming implementation shall, within its resource limits, accept and correctly execute that program.
— If a program contains a violation of any diagnosable rule, a conforming implementation shall issue at least one diagnostic message, except that
— 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.
Conclusion
A compiler is free to do whatever it wants to do. Try the same code on Comeau Online (a more conforming compiler).
I get this error
"function "main" may not be called or have its address taken"