Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Surprising behavior of literal type at runtime

Tags:

c++

clang

c++14

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.

like image 980
Oleg Bogdanov Avatar asked Mar 02 '17 21:03

Oleg Bogdanov


People also ask

Which statement is true about string literal type?

String is a value type. String literals can contain any character literal including escape sequences.

What is an example of a string literal?

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."'

What is a literal annotation?

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.


1 Answers

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.

like image 83
Barry Avatar answered Dec 31 '22 07:12

Barry