Different compiler behavior for expression: auto p {make_pointer()};

后端 未结 1 1605
傲寒
傲寒 2020-12-02 00:06

Which is the correct behaviour for the following program?

// example.cpp

#include 
#include 

struct Foo {
  void Bar() const          


        
相关标签:
1条回答
  • 2020-12-02 00:13

    Tl;DR

    This behavior is subject to a proposal and an Evolution Working Group issue. There is some ambiguity as to whether this is considered a C++14 defect or a C++1z proposal. If it turns out to be a C++14 defect then gcc's behavior is correct for C++14. On the other hand if this is really a C++1z proposal then clang and icpc are exhibiting correct behavior.

    Details

    It looks like this case is covered by N3681 which says:

    Auto and braced initializers cause a teachability problem; we want to teach people to use uniform initialization, but we need to specifically tell programmers to avoid braces with auto. In C++14, we now have more cases where auto and braces are problematic; return type deduction for functions partially avoids the problem, since returning a braced-list won't work as it's not an expression. However, returning an auto variable initialized from a braced initializer still returns an initializer_list, inviting undefined behaviour. Lambda init captures have the same problem. This paper proposes to change a brace-initialized auto to not deduce to an initializer list, and to ban brace-initialized auto for cases where the braced-initializer has more than one element.

    and provides the following examples:

    auto x = foo(); // copy-initialization
    auto x{foo}; // direct-initialization, initializes an initializer_list
    int x = foo(); // copy-initialization
    int x{foo}; // direct-initialization
    

    So I think clang is currently correct, the latest version of clang provides this warning:

    warning: direct list initialization of a variable with a deduced type will change meaning in a future version of Clang; insert an '=' to avoid a change in behavior [-Wfuture-compat]

    From EWG issue 161 that N3922 was adopted for this.

    As Praetorian notes the proposal recommends this is a C++14 defect:

    Direction from EWG is that we consider this a defect in C++14.

    but clang's C++1z implementation status notes this as a C++1z proposal which is not implemented.

    So if this is a C++14 defect, that would make gcc correct but it is not clear to me if this is really a defect or a proposal.

    T.C. points out in a comment here that it seems like the clang developers do intended to back-port this. It has not happened and it is not clear why.

    0 讨论(0)
提交回复
热议问题