c++ - 未构造对象的调用方法 : Legal?

标签 c++ c++11

如果为对象预留内存(例如,通过 union )但构造函数尚未被调用,调用对象的非静态方法之一是否合法,假设该方法不依赖于值任何成员变量?

我做了一些研究,发现了一些关于“变体成员”的信息,但找不到与此示例相关的信息。

class D {
 public:
  D() { printf("D constructor!\n"); }
  int a = 123;
  void print () const {
    printf("Pointer: %p\n", &a);
  };
};

class C {
 public:
  C() {};
  union {
    D memory;
  };
};

int main() {
  C c;
  c.memory.print();
} 

在这个例子中,我在没有调用构造函数的情况下调用 print()。目的是稍后调用构造函数,但即使在调用构造函数之前,我们也知道变量 a 的位置。显然 a 的值此时未初始化,但 print() 不关心该值。

这似乎在使用 gcc 和 clang 为 c++11 编译时按预期工作。但我想知道我是否在这里调用了一些非法或未定义的行为。

最佳答案

我相信这是未定义的行为。您的变体成员 C::memory 尚未初始化,因为 C 的构造函数未提供初始化器 [class.base.init]/9.2 .因此,c.memory 的生命周期尚未从您调用方法 print() 的那一刻开始 [basic.life]/1 .基于[basic.life]/7.2 :

Similarly, before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any glvalue that refers to the original object may be used but only in limited ways. […] The program has undefined behavior if:

  • […]
  • the glvalue is used to call a non-static member function of the object, or
  • […]

强调我的

注意:我指的是 current C++ standard draft然而,上面的相关措辞与 C++11 基本相同,除了在 C++11 中,D 具有非平凡初始化这一事实至关重要,因为您正在做的事情可能否则在 C++11 中可能没问题……

关于c++ - 未构造对象的调用方法 : Legal?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55699626/

相关文章:

c++ - 在 C++ 中不使用 char 类型定义 '999e999' 值

c++11 - Boost 链接错误 : 'B5cxx11' symbols missing

c++ - 如果左值不再用于其定义范围,编译器是否允许将左值转换为右值引用?

c++ - 为什么 is_lock_free 是成员函数?

c++ - 在 C++11 中,什么时候将指针传递给另一个线程会出现竞争条件?

c++ - Terrain GeoMipMapping LOD - 消除裂缝

c++ - 如何使用 Loki 的小对象分配器?

c++ - 通过 const 引用获取字符串

c++ - 如何检测 Wine 是从 Linux 运行还是从 C++ 的 mac OS 环境运行?

C++流到内存