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.