静态const char*和const char之间的区别*

Wil*_*agh 15 c++ string static char

有人可以解释下面如何处理2个代码片段的区别吗?它们肯定会编译成不同的汇编代码,但我试图理解代码的行为方式可能不同.我知道字符串文字被抛入只读内存并且实际上是静态的,但是它与下面的显式静态有何不同?

struct Obj1
{
    void Foo()
    {
        const char* str( "hello" );
    }
};
Run Code Online (Sandbox Code Playgroud)

struct Obj2
{
    void Foo()
    {
        static const char* str( "hello" );
    }
};
Run Code Online (Sandbox Code Playgroud)

joh*_*nes 18

使用静态版本时,只有一个变量存储在某个地方,每当执行该函数时,将使用完全相同的变量.即使是递归调用.

对于每个函数调用,非静态版本将存储在堆栈中,并在每次调用后销毁.

现在你的例子在编译器的实际操作方面有点复杂,所以让我们先看一个更简单的案例:

void foo() {
    static long i = 4;
    --i;
    printf("%l\n", i);
}
Run Code Online (Sandbox Code Playgroud)

然后是这样一个主要的东西:

int main() {
    foo();
    foo();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

将打印

3
2
Run Code Online (Sandbox Code Playgroud)

而与

void foo() {
    long i = 4;
    --i;
    printf("%l\n", i);
}
Run Code Online (Sandbox Code Playgroud)

它会打印出来

3
3
Run Code Online (Sandbox Code Playgroud)

现在用你的例子你有一个const,所以值不能改变,所以编译器可能会玩一些技巧,虽然它通常对生成的代码没有影响,但有助于编译器检测错误.然后你有一个指针,并且注意静态对指针本身有影响,而不是它指向的值.因此,您的示例中的字符串"hello"很可能会被放置在二进制文件的.data段中,并且只要程序存在一次就可以存活,与静态事物无关.


sbi*_*sbi 10

本地静态变量在第一次遇到定义时初始化,但在函数退出时不会被破坏.所以它在函数的调用之间保持其值.

const这种情况下,这并不是所有有用的 - 至少,只要构造常量值与地址分配一样可忽略的性能.(如果const对象不是常量表达式,或者表达式需要相当多的资源来创建 - 比如const Foo bar = foobar();,在哪里foobar()可能需要相当长的时间 - ,差异可能会变得很重要.)

它确实产生影响的地方是你想要为每个引用或指针返回对象:你不能返回一个引用或指向本地对象的指针,除非它是一个本地静态对象.(感谢Matthieu指出这一点.)但是,当你想要使用它时,你需要记住,局部静态本质上是线程不安全的.


Tho*_*ews 8

我发现有些编译器对这两种编译器的处理方式不同.

该版本const char *将数据从只读位置复制到堆栈上的变量.

The version with static const char * references the data in the read-only location (no copy is performed).

I discovered this difference while stepping through the assembly code of a function, using the debugger. I suggest you either print out the assembly code or step through, at the assembly language level, with a debugger to find the exact truth.