为什么m_data的填充未被初始化?

huangapple go评论79阅读模式
英文:

Can someone explain to me why the padding of m_data is not initialized?

问题

I don't understand why the padding after m_data, when the copy constructor constructs the object, is not initialized to 0 in an optimized build like -O2. The default constructor always seems to initialize it. I haven't tried yet other special member functions.

Is this behaviour implementation-defined? Not defined?

Is there a way to initialize it?

Compiler Explorer

Thanks

英文:

I don't understand why the padding after m_data, when the copy constructor constructs the object, is not initialized to 0 in an optimized build like -O2. The default constructor always seems to initialize it. I haven't tried yet other special member functions.

Is this behaviour implementation-defined? Not defined?

Is there a way to initialize it?

Compiler Explorer

Thanks

#include <climits>
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <limits>
#include <span>

void print(std::span<const std::byte> const span)
{
  for (auto const i : span) {
    std::cout << std::to_integer<int>(i) << ' ';
  }
  std::cout << '\n';
}

struct Foo {
  Foo()
  {}
  Foo(const Foo&)
  {}
  /*alignas(1)*/ std::byte m_data[1] = {};
  uint32_t val = INT_MAX;
};

inline auto objAsBytes(const auto& obj)
{
  return std::as_bytes(std::span { std::addressof(obj), 1 });
}

int main()
{
  auto foo = Foo {};
  std::span fooAsBytes = objAsBytes(foo);
  std::cout << "fooAsBytes\n";
  print(fooAsBytes);

  auto fooCopy = foo;
  std::span fooCopyBytes = objAsBytes(fooCopy);
  std::cout << "fooCopyBytes\n";
  print(fooCopyBytes);

  Foo fooAssign;
  fooAssign = foo;
  std::span fooAssignBytes = objAsBytes(fooAssign);
  std::cout << "fooAssignBytes\n";
  print(fooAssignBytes);
}

答案1

得分: 1

After more research today, I found a good explanation.

First, I found a good related question, Does C++ standard guarantee the initialization of padding bytes to zero for non-static aggregate objects?

It first mentions cppreference zero-initialization,

c++ standard dcl.init.general#6 which states this:

> if T is a (possibly cv-qualified) non-union class type, its padding bits ([basic.types.general]) are initialized to zero bits and each non-static data member, each non-virtual base class subobject, and, if the object is not a base class subobject, each virtual base class subobject is zero-initialized;

The question also mentions differences between GCC and Clang regarding zero-initialization. It is not my question but good to mention.

The reason zero-initialization is not happening is a mix of having user-defined default and copy constructors and default member initializers instead of value initialization.

英文:

After more research today, I found a good explanation.

First, I found a good related question, Does C++ standard guarantee the initialization of padding bytes to zero for non-static aggregate objects?

It first mentions cppreference zero-initialization,

c++ standard dcl.init.general#6 which states this:

> if T is a (possibly cv-qualified) non-union class type, its padding bits ([basic.types.general]) are initialized to zero bits and each non-static data member, each non-virtual base class subobject, and, if the object is not a base class subobject, each virtual base class subobject is zero-initialized;

The question also mentions differences between GCC and Clang regarding zero-initialization. It is not my question but good to mention.

The reason zero-initialization is not happening is a mix of having user-defined default and copy constructors and default member initializers instead of value initialization.

huangapple
  • 本文由 发表于 2023年5月10日 14:13:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76215360.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定