[cfe-dev] Calling main() is ub based optimizations

Mehdi Amini via cfe-dev cfe-dev at lists.llvm.org
Mon Nov 14 08:43:01 PST 2016


> On Nov 14, 2016, at 8:38 AM, David Chisnall <David.Chisnall at cl.cam.ac.uk> wrote:
> 
> On 14 Nov 2016, at 16:29, Mehdi Amini <mehdi.amini at apple.com <mailto: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.

Right, but when you form a program by mixing C and C++, I’m not sure how you can escape rules from both standard that applies to “the program” as whole.


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

Yes, that’s not great, but you can run into this issue with any “program-wide” rules in standards (luckily there’s not that many).

— 
Mehdi

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20161114/2da30501/attachment.html>


More information about the cfe-dev mailing list