是否省略了冗余默认初始化?

E_n*_*ate 6 d initialization

与C或C++相比,D的一个奇怪方面是,当未提供赋值时,变量根据其类型进行默认初始化.

int foo() {
    int o; // int.init == 0
    o++;
    return o; // returns 1
}
Run Code Online (Sandbox Code Playgroud)

与C和C++相比,C和C++只是将变量留给潜在的垃圾,D确保从几乎所有类型的变量都不会读取垃圾.然而,考虑到这个简单的,仅仅是假设的函数,r在被设置之前永远不会被读取i,并且可以肯定最终会发生赋值.

int foo2(int n) {
    assert(n > 0 && n < 20);
    int r;
    for (int i = n ; ; i+=7) {
        if (i % 3 == 0) {
            r = i;
            break;
        }
    }
    return r;
}
Run Code Online (Sandbox Code Playgroud)
  1. 在确定将来没有先前读取的情况下定义变量的情况下,根据标准,默认初始化是否仍会发生?
  2. 从DMD/GDC编译器中可以知道它们是否已经优化出来(例如,当从未从变量读取默认值时省略默认初始化)?
  3. 如果没有上述内容,是否有一个很好的解决方案来拥有一个完全未初始化的变量?

Vla*_*eev 7

  1. 在确定将来没有先前读取的情况下定义变量的情况下,根据标准,默认初始化是否仍会发生?

由于D没有值类型构造函数(默认struct构造函数),因此初始化不应该有任何副作用,因此允许编译器对其进行优化.我相信这是死亡分配消除的一个子集.

  1. 从DMD/GDC编译器中可以知道它们是否已经优化出来(例如,当从未从变量读取默认值时省略默认初始化)?

语言规范没有对实现必须执行的优化施加约束.上面的例子是非平凡的,所以如果例如DMD不会优化它,或者如果GDC将处于最大优化级别,我不会感到惊讶.

  1. 如果没有上述内容,是否有一个很好的解决方案来拥有一个完全未初始化的变量?

是: int r = void;