d这段代码哪里错了

原文

int[] numbersForLaterUse;

void foo(int[] numbers...) {
   numbersForLaterUse = numbers;
}

struct S {
  string[] namesForLaterUse;

  void foo(string[] names...) {
     namesForLaterUse = names;
  }
}

他说上面的代码是一个bug,因为:
foo()独立函数和S.foo()成员函数都错了,因为它们把切片存储到,自动生成的仅在执行可变函数时有效的上的临时数组.”
问题是,没错啊.
你正在见证未定义行为的奇妙之处.无效代码仍然可产生你所希望的结果,或产生垃圾结果,或崩溃,或完全做其他事情.仅因为运行一次它做了一件事,不表明下次运行它也会做一样的.

int[] numbersForLaterUse;

void foo(int[] numbers...) {
   numbersForLaterUse = numbers; /*不要,坏的*/
}

void bar()
{
    int[3] n = [1, 2, 3];
    foo(n);
}

void main()
{
    bar();
    import std.stdio;
    writeln(numbersForLaterUse); /*打印垃圾*/
}

@safe标记,看看编译器输出.再试试:

int[] numbersForLaterUse;

void foo(int[] numbers...) {
   numbersForLaterUse = numbers;
}

struct S {
  string[] namesForLaterUse;

  void foo(string[] names...) {
     namesForLaterUse = names;
  }
}

void whatwentwrong() {
    import std.stdio;
    writeln(numbersForLaterUse);
}

void whatelsewentwrong(S s) {
    import std.stdio;
    writeln(s.namesForLaterUse);
}

void badCodeBad() {
  foo(1, 2, 3, 4, 5);
}

S alsoReallyBad() {
  S s;
  s.foo("hello", "world!");
  return s;
}

void main() {
  badCodeBad();
  whatwentwrong();

  auto s = alsoReallyBad();
  whatelsewentwrong(s);
}

结论:
(1)把切片存储到超过其生存期栈位置不好.
(2)尽可能使用@safe.

posted @ 2022-12-17 12:47  zjh6  阅读(31)  评论(0)    收藏  举报  来源