Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<memory>: std::construct_at(s, " ") did not evaluate to a constant #2467

Closed
hewillk opened this issue Jan 11, 2022 · 12 comments
Closed

<memory>: std::construct_at(s, " ") did not evaluate to a constant #2467

hewillk opened this issue Jan 11, 2022 · 12 comments
Labels
compiler Compiler work involved external This issue is unrelated to the STL

Comments

@hewillk
Copy link
Contributor

hewillk commented Jan 11, 2022

#include<string>
#include<memory>

constexpr bool b = [] {
  std::string s[1];
  std::construct_at(s, " ");
  return true;
}();

https://godbolt.org/z/jdx7oGnMn

MSVC-trunk rejects it with:

<source>(4): error C2131: expression did not evaluate to a constant
<source>(6): note: a non-constant (sub-)expression was encountered

I don't know if this is a language bug or a library bug, please correct me if I'm missing something.

@miscco
Copy link
Contributor

miscco commented Jan 11, 2022

This is a clear compiler bug. You can play with other forms aka assignment etc that work. So it seems to be related to std::construct_at.

Strangely using a simple literal type works.

Please file a developer community ticket

@CaseyCarter
Copy link
Member

This won't work in debug mode since we allocate memory in the default constructor of all containers and that memory isn't deallocated if you reuse the storage for the container without destruction.

@CaseyCarter
Copy link
Member

CaseyCarter commented Jan 11, 2022

Correction: at compiletime the default constructor always allocates memory - we don't SSO in constant expressions. This is not a compiler bug. It may be a library bug?

@CaseyCarter CaseyCarter added decision needed We need to choose something before working on this question Further information is requested labels Jan 11, 2022
@miscco
Copy link
Contributor

miscco commented Jan 11, 2022

I doubt that this is the issue here.

For once the error is quite different.

Secondly it also fails when destroying the allocation with destroy_at

@hewillk
Copy link
Contributor Author

hewillk commented Jan 11, 2022

This OP is simplified from the following, if it helps.

#include<string>
#include<vector>

constexpr bool b = [] {
  std::vector<std::string> v;
  v.push_back(" "); // ok
  v.emplace_back(" "); // not ok
  return true;
}();

https://godbolt.org/z/PMdTo5sK1

@CaseyCarter
Copy link
Member

CaseyCarter commented Jan 11, 2022

I doubt that this is the issue here.

I doubt it's the only issue here.

For once the error is quite different.

Secondly it also fails when destroying the allocation with destroy_at

Clang compiles successfully with the destroy_at, MSVC does not. An altered program that includes such a destroy_at call would indicate a compiler bug.

This OP is simplified from the following, if it helps.

It does, that example is orders of magnitude more motivating than the sample in the OP.

@CaseyCarter
Copy link
Member

CaseyCarter commented Jan 11, 2022

Less reduced, but more library-free:

#include <memory>
#include <string>

constexpr const char *space = " ";

static_assert([] {
  std::string *v = std::allocator<std::string>{}.allocate(4);

  std::construct_at(v + 0, std::string{}); // OK
  std::construct_at(v + 1, space);         // OK
  std::construct_at(v + 2, " ");           // note: a non-constant (sub-)expression was encountered
  std::destroy_at(v + 2);
  std::destroy_at(v + 1);
  std::destroy_at(v + 0);

  std::allocator<std::string>{}.deallocate(v, 4);
  return true;
}()); // error C2131: expression did not evaluate to a constant

@CaseyCarter CaseyCarter added compiler Compiler work involved and removed question Further information is requested decision needed We need to choose something before working on this labels Jan 11, 2022
@miscco
Copy link
Contributor

miscco commented Jan 11, 2022

I also checked with a local string_view of a whitespace, which also works. Seems that @cdacamar will have a lot of fun with all the string issues

@miscco
Copy link
Contributor

miscco commented Jan 11, 2022

Luckily it has nothing to do with std::string https://godbolt.org/z/TG9PqsvoT

@miscco
Copy link
Contributor

miscco commented Jan 11, 2022

Removing all the library code I believe this is the minimal example
https://godbolt.org/z/zj1dGzsK3

namespace std {
    template <class _Ty, class... _Types>
    constexpr _Ty* construct_at(_Ty* _Location, _Types&&... _Args) {
        return ::new (const_cast<void*>(static_cast<const volatile void*>(_Location))) _Ty(static_cast<_Types&&>(_Args)...);
    }   
}

struct meow {
    constexpr meow() = default;
    constexpr meow(const char*) {};
};

static_assert([] {
  meow v[1];
  std::construct_at(v, " ");
  return true;
}());

@miscco
Copy link
Contributor

miscco commented Jan 11, 2022

Filed DevCom-1634430

@CaseyCarter
Copy link
Member

Thanks for filing the compiler bug, @miscco! Since this is not an STL bug, and anyone interested can follow the compiler bug on DevCom, I'm closing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler Compiler work involved external This issue is unrelated to the STL
Projects
None yet
Development

No branches or pull requests

3 participants