静态变量对const局部变量有影响吗?

时间:2019-03-01 10:27:57

标签: c++ static const

想象一下以下声明:

void foo(){
    const std::array<int, 80000> arr = {/* a lot of different values*/};
    //do stuff
}

第二个:

void foo(){
    static const std::array<int, 80000> arr = {/* a lot of different values*/};
    //do stuff
}

如果有的话,两者之间可能会有哪些性能差异?这些解决方案中是否有任何危险?

4 个答案:

答案 0 :(得分:15)

暂时忘记该数组。这混淆了两个独立的问题。您已经得到解决寿命和存储问题的答案。我将解决初始化问题。

void f() {
    static const int x = get_x();
    // do something with x
}

void g() {
    const int x = get_x();
    // do something with x
}

这两者的区别在于,第一个只会在第一次调用get_x()时才调用f()x会在程序的其余部分保留该值。每次调用get_x()时,第二个将调用g()

如果get_x()在后​​续调用中返回不同的值,则很重要:

int current_x = 0;
int get_x() { return current_x++; }

答案 1 :(得分:12)

  

这些解决方案中是否有任何危险?

非静态是危险的,因为阵列很大,并且为自动存储保留的内存是有限的。根据系统和配置的不同,该阵列可能会使用大约30%的自动存储空间。因此,它大大增加了堆栈溢出的可能性。

尽管优化器肯定可以避免在堆栈上分配内存,但是有充分的理由使您希望未优化的调试版本也不会崩溃。

答案 2 :(得分:5)

  

这两者之间可能存在性能差异吗?这些解决方案是否存在任何危险?

区别完全取决于您使用foo()的方式。

第一种情况:(低概率):您的实现是只调用一次foo(),也许您已经创建了单独的函数来按惯例划分代码逻辑。在这种情况下,声明为static非常不好,因为静态变量或对象保留在内存中直到程序结束。因此,请想象您的变量不必要地占用了内存。

第二种情况:(高概率):您的实现方式是您将一次又一次调用foo()。这样,非静态对象将被分配并一次又一次地释放。这将占用大量的CPU时钟周期,这是不希望的。在这种情况下,请使用static。

答案 3 :(得分:2)

在这种特定情况下,需要考虑在具有初始化的变量上使用static

根据C ++ 17标准:

  

6.7.1静态存储持续时间[basic.stc.static]
  ...
  2如果静态存储持续时间为的变量已初始化或具有副作用的析构函数,则即使看起来未使用,也不得将其消除,除非可以按照15.8的规定删除类对象或其复制/移动。