简体   繁体   中英

Surprising behavior of literal type at runtime

I'm a bit perplexed by the behavior of this code compiled with clang 3.9:

struct A {
    constexpr A() = default;
    A(const A&) = delete;
    constexpr A(A&&) {}
    A& operator =(const A&) = delete;
    constexpr A& operator =(A&&) { return *this; }
    constexpr operator bool() const { return &self == this; }
private:
    A& self{*this};
};

constexpr A fooA() { return {}; }    

int main(int argc, const char * argv[]) {
    static_assert(fooA(), "");
    return fooA();
}

Godbolt link: https://godbolt.org/g/CDFXAc

Static/compile-time evaluation is happening correctly for fooA ; however at runtime the constructor seems to be omitted completely. The static_assert is not fired (as expected) but main still returns 0. Is that because A is a literal type or is it because of a compiler bug?

In case of the former any references to the standard would be appreciated.

Here's an even more reduced example:

struct A {
    constexpr A() : self(this) { }
    A* self;
};

int main() {
    constexpr A a{};
}

Neither gcc nor clang accept this code as they do not like the usage of this in the initializer. However, this is allowed in a constant expression as long as it's in a constexpr constructor, since N3652 . MSVC gets this right.

问题是输出取决于是否执行了复制省略(如果没有, self被初始化为临时,因此fooA()变为非const并且其声明fooA()不正确,那么你会得到意想不到的行为。在标准中有在这种情况下没有强烈要求复制省略(对于c ++ 14),所以你从不同的编译器得到不同的行为。你可以在这份报告中获得这个问题的更多细节

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM