https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109890

            Bug ID: 109890
           Summary: vector's constructor doesn't start object lifetimes
                    during constant evaluation
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: barry.revzin at gmail dot com
  Target Milestone: ---

>From StackOverflow (https://stackoverflow.com/q/76269606/2069064), clang
rejects this code when compiling with libstdc++:

#include <vector>

consteval auto bar(int n){
    std::vector<int> v(n);
    return v[0];
}
constexpr auto m = bar(5);

This is because libstdc++ basically does something like this:

#include <memory>

class V {
    int* p;
    int n;
    std::allocator<int> alloc;

public:
    constexpr V(int n)
        : n(n)
    {
        p = alloc.allocate(n);

        // fill with 0s?
        for (int i = 0; i != n; ++i) {
            p[i] = 0;
        }
    }

    constexpr ~V() {
        alloc.deallocate(p, n);
    }
};

consteval auto bar(int n) {
    V v(n);
    return n;
}
static_assert(bar(5) == 5);

And clang is more picky about the assignment there - it doesn't like just
writing p[0] = 0, because the int's lifetime hasn't started yet. gcc accepts
the above though. 

I think that's... technically correct (if pedantic) and libstdc++'s path needs
to do a construct_at somewhere.
  • [Bug libstdc++/109890] New: vec... barry.revzin at gmail dot com via Gcc-bugs

Reply via email to