简体   繁体   中英

std::allocator_traits::construct with const pointer

The following code compiles fine:

#include <iostream>
#include <memory>
int main()
{
const int * a = new int(5);

std::cout << *a << std::endl; // Prints 5

// *a = 5; // Compiler error.
using at = std::allocator_traits<typename std::allocator<int>>;
auto alloc = std::allocator<int>();
at::construct(alloc, a);

std::cout << *a << std::endl; // Prints 0
}

Under the hood libstdc++ does

::new((void*)a) int;

but a is const !

Is this undefined behavior? Or does placement new not count as modifying? I modified the value of *a , which is const. To my understanding this is not allowed:

Modifying a const object through a non-const access path and referring to a volatile object through a non-volatile glvalue results in undefined behavior.

https://en.cppreference.com/w/cpp/language/const_cast

TL;DR : Fine until C++2a, thereafter std::allocator_traits<std::allocator<int>>::construct() will be more demanding of the passed pointer.


Well, std::allocator_traits::construct() uses static_cast<void*> since it was introduced , unless the allocator provides it.

And while std::allocator::construct() was deprecated in C++17 and will be removed in C++2a, it always used a c-style cast.

Thus, it's syntactically valid until C++2a.


And as the pointed-to object itself is not const , only the pointer it is accessed through having that qualifier, casting away const and modifying is perfectly legal.

As the pseudo-dtor for int is trivial, it doesn't even matter that it isn't called before constructing a new one on top of it.

const int* a specify that the value contained by the memory slot pointed by a is constant, but not the pointer itself.

#include <memory>

int main()
{
    const int * a = new int;

    a = nullptr; // Compile fine
    *a = 1; // Won't compile

    return 0;
}

You were expecting your code to behave like:

#include <memory>

int main()
{
    int* const a = new int;

    a = nullptr; // Won't compile
    *a = 1; // Compile fine

    return 0;
}

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM