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.
String is a value type. String literals can contain any character literal including escape sequences.
A string literal is a sequence of zero or more characters enclosed within single quotation marks. The following are examples of string literals: 'Hello, world!' 'He said, "Take it or leave it."'
Literal Annotation ExampleThe Literal type needs at least one parameter, e.g. Literal["foo"] . That means that the annotated variable can only take the string "foo" . If you want to accept "bar" as well, you need to write Literal["foo", "bar"] . A complete example: from typing import Literal.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With