小编Tar*_*ras的帖子

是否修改 const 对象的内部字节未定义行为,以防它包含由放置 new 构造的另一个对象?

考虑以下示例:

#include <new>

struct FunctionObject
{
    int operator()() // non-const, modifies the state of this object
    {
        i += 1;
        j += 2;
        return i + j;
    }

    int i = 0;
    int j = 0;
};

struct Wrapper
{
    explicit Wrapper(const FunctionObject& input_object)
    {
        constructed_object = ::new (buffer) FunctionObject(input_object);
    }

    ~Wrapper()
    {
        constructed_object->~FunctionObject();
    }

    int operator()() const // const, but invokes the non-const operator() of the internal FunctionObject
    {
        return (*constructed_object)(); // this call modifies the internal bytes of …
Run Code Online (Sandbox Code Playgroud)

c++ standards placement-new undefined-behavior

8
推荐指数
1
解决办法
170
查看次数

为什么C++编译器不会优化对结构数据成员的读写,而不是独特的局部变量?

我正在尝试创建一些POD值的本地数组(例如double),max_size在编译时已知固定,然后读取运行size时值(size <= max_size)并处理size该数组中的第一个元素.

现在的问题是,为什么不编译器消除堆读取和写入时arr,并size放置到同一个struct/ class,而不是那里的情况arrsize是独立的局部变量?

这是我的代码:

#include <cstddef>
constexpr std::size_t max_size = 64;

extern void process_value(double& ref_value);

void test_distinct_array_and_size(std::size_t size)
{
    double arr[max_size];
    std::size_t arr_size = size;

    for (std::size_t i = 0; i < arr_size; ++i)
        process_value(arr[i]);
}

void test_array_and_size_in_local_struct(std::size_t size)
{
    struct
    {
        double arr[max_size];
        std::size_t size;
    } array_wrapper;
    array_wrapper.size = size;

    for (std::size_t i = 0; i …
Run Code Online (Sandbox Code Playgroud)

c++ arrays optimization boost compilation

7
推荐指数
1
解决办法
302
查看次数

在单继承的情况下,C++ 是否保证 Base 子对象的地址与其派生对象的地址相同?

这是一段代码:

struct Base
{
    virtual void Foo() = 0;
    virtual ~Base() { }
};

struct Derived : Base
{
    virtual void Foo() override { }
    unsigned long long some_new_data_members[42];
};

int test_offset()
{
    Derived object{};
    Base* base_subobject = &object;

    return reinterpret_cast<unsigned char*>(base_subobject) - reinterpret_cast<unsigned char*>(&object);
}
Run Code Online (Sandbox Code Playgroud)

test_offset我检查过的所有版本的 gcc、clang 和 msvc 编译器上,该函数总是返回 0。

我的问题是:C++ 标准是否保证在和之间存在单继承的情况下此函数将始终返回 0 ?如果没有,有人可以提供一个现实生活中的例子(也许有一些异国情调的平台),其中这段代码将返回不同于 0 的东西?BaseDerived

请不要回答多重继承!


更新:

正如用户VTT所指出的,这样的代码可能会导致非零偏移:

struct Base
{
};

struct Derived : Base
{ …
Run Code Online (Sandbox Code Playgroud)

c++ memory inheritance memory-management

5
推荐指数
1
解决办法
193
查看次数

初始化不可移动对象的数组:为什么这样的代码无法在GCC上编译?

这是代码示例,其中Test是一个具有某些成员和用户定义的构造函数的不可复制不可移动的类virtual,并且B是包含原始(C样式)Test对象数组的类:

class Test
{
public:
    Test() = delete;

    Test(const Test&) = delete;
    Test(Test&&) = delete;
    Test& operator=(const Test&) = delete;
    Test& operator=(Test&&) = delete;

    Test(int a, int b) : a_(a), b_(b) {}
    virtual ~Test() {}

    int a_;
    int b_;
};

//----------------

class B
{
public:
/*(1)*/ B() : test_{{1, 2}, {3, 4}} {} // Does not compile on GCC, but compiles on Clang and MSVC

private:
        Test test_[2];
};

//---------------- …
Run Code Online (Sandbox Code Playgroud)

c++ arrays gcc language-lawyer

5
推荐指数
1
解决办法
137
查看次数

为什么大多数平台上都没有'aligned_realloc'?

MSVC具有自己的非标准功能_aligned_malloc_aligned_realloc并且_aligned_free

C ++ 17和C11已经介绍(std::)aligned_alloc,其结果可以分配freerealloc。但是realloc不能用于实际重新分配由返回的内存aligned_alloc,因为它没有对齐参数,因此不能保证返回的指针将正确对齐。

我什至找不到任何非标准扩展,它们可以在Microsoft Windows / Visual C ++以外的平台上重新分配对齐的内存(保留对齐)。

我搜索错误_aligned_realloc吗,还是在POSIX和其他平台上确实没有其他选择?

如果是这样的话,

  1. 为什么?
  2. 在那些平台上可以代替使用什么?有什么比调用aligned_alloc新对齐,然后做memcpyfree荷兰国际集团成功的老猎狗?

c c++ memory-management c11 c++17

4
推荐指数
2
解决办法
235
查看次数

为什么 std 范围算法为右值参数返回 std::ranges::dangling 而不是......好吧,只是工作?

这是我(简化)尝试实现一个ranges::min_element适用于左值和右值参数的版本:

#include <iterator>
#include <algorithm>
#include <type_traits>
#include <utility>

namespace better_std_ranges
{
    template<typename Range>
    constexpr auto min_element(Range& range)
    {
        using std::begin;
        using std::end;
        return std::min_element(begin(range), end(range));
    }

    template<typename Range>
    constexpr auto min_element(Range&& range)
    {
        static_assert(!std::is_reference_v<Range>, "wrong overload chosen");

        class _result_iterator_type // todo: inherit from some crtp base that will provide lacking operators depending on _underlying_iterator_type::iterator_category
        {
            using _underlying_iterator_type = std::decay_t<decltype(std::begin(std::declval<Range&>()))>;

        public:
            explicit constexpr _result_iterator_type(Range&& range) noexcept(std::is_nothrow_move_constructible_v<Range>)
            : _underlying_range{std::move(range)}
            , _underlying_iterator(::better_std_ranges::min_element(_underlying_range))
            {
            }

            using difference_type   = typename _underlying_iterator_type::difference_type;
            using …
Run Code Online (Sandbox Code Playgroud)

c++ c++20 std-ranges

1
推荐指数
1
解决办法
191
查看次数