[llvm-bugs] [Bug 27221] member function of template instantiated even though only declaration is needed

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Apr 6 08:04:40 PDT 2016


https://llvm.org/bugs/show_bug.cgi?id=27221

David Blaikie <dblaikie at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
                 CC|                            |dblaikie at gmail.com
         Resolution|---                         |INVALID

--- Comment #4 from David Blaikie <dblaikie at gmail.com> ---
(In reply to comment #3)
> Sorry, if I am a bit obnoxious about this. But I am having trouble with the
> given explanation:
> 
> If I remove the definition of the move constructor, the code compiles and
> links just fine with every compiler I could get my hands on (gcc, clang,
> msvc).
> 
> template<typename T>
> struct X
> {
>   X() = default;
> 
>   X(X&&);
> };
> 
> auto impl() -> X<int>
> {
>   return {};
> }
> 
> auto test() -> decltype(impl())
> {
>   return impl();
> }
> 
> int main()
> {
>   test();
> }
> 
> 
> Thus, the implementation does not seem to be required. 

It is required by the standard, but not by any specific implementation you've
found so far (& perhaps any implementation that exists).

> Thus, it is not deterministic whether or not this code can be compiled.

It is deterministic with the current compiler behavior - it checks that the
implementation is valid whether or not it chooses to use that implementation.
That makes it more deterministic than the behavior you're suggesting (where it
doesn't check the implementation unless it chooses to use it - so your code
could flap between compiling and not compiling depending on whether the
compiler chose to elide the copy or not)

This isn't a bug in the standard either, but quite intentional that the
standard describes a set of possible executions, not one specific one.
Implementations may provide anything within that set at any time.

For example: f(g(), h()); the standard does not require that g execute before
h, or that h execute before g. Just that one of those two things happens (g and
h cannot execute concurrently, for example). These things are built into the
standard quite intentionally to allow implementation choices that may be better
on a given platform, or may be sufficient to implement the language, but not
the most advanced behavior (eg: a simple compiler that does no RVO would be a
valid implementation - so the standard doesn't force the compiler to do RVO
heroics for it to meant the minimum bar for being a valid C++ compiler)

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160406/1f8c50b3/attachment-0001.html>


More information about the llvm-bugs mailing list