[cfe-dev] Calling main() is ub based optimizations
David Chisnall via cfe-dev
cfe-dev at lists.llvm.org
Mon Nov 14 08:38:14 PST 2016
On 14 Nov 2016, at 16:29, Mehdi Amini <mehdi.amini at apple.com> wrote:
>
>
>> On Nov 14, 2016, at 3:11 AM, David Chisnall via cfe-dev <cfe-dev at lists.llvm.org> wrote:
>>
>> On 14 Nov 2016, at 10:58, Ben Taylor <brtaylor92 at gmail.com> wrote:
>>>
>>> The relevant piece of standardese seems to be 3.6.1.3 in the C++17 working draft (n4606) standard, which reads in part:
>>>
>>> "The function main shall not be used within a program. The linkage (3.5) of main is implementation-defined. A program that defines main as deleted or that declares main to be inline, static, or constexpr is ill-formed. The main function shall not be declared with a linkage-specification (7.5). A program that declares a variable main at global scope or that declares the name main with C language linkage (in any namespace) is ill-formed."
>>>
>>> So the cases you suggest, by my reading, should not be UB but rather a compile error.
>>
>> It sounds as if calling main from C++ should be a compile error. It’s not clear what’s expected to happen if a C compilation unit calls a C++ main.
>
> Isn’t the very beginning "The function main shall not be used within a program” enough?
No, because this rule does not exist in the C standard and, from the perspective of a C compilation unit the main function is just another C function. The fact that a function in another compilation unit is implemented in a different language makes calling it UB. Consider two compilation units written in the common subset of C and C++:
Compilation unit A contains main(), which calls foo().
Compilation unit B calls main() the first time that it’s called, and returns otherwise.
If these are both compiled as C, this is valid code.
If these are both compiled as C++, then compilation unit B should be a compile-time error.
If A is compiled as C and B is compiled as C++, then B should be a compile-time error.
If A is compiled as C++ and B is compiled as C then we have a problem: is is well-defined behaviour in C for B to contain a call to main(), but it is UB in C++ for the main defined in A to be called.
This means that we don’t know if B is relying on UB unless we know whether A is compiled as C or C++ code. This is a horrible situation: flipping a compiler switch in A changes whether B is UB or not.
David
More information about the cfe-dev
mailing list