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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2928863/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 11:31:25  来源:igfitidea点击:

Difference between static const char* and const char*

c++stringstaticchar

提问by Will MacDonagh

Could someone please explain the difference in how the 2 snippets of code are handled below? They definitely compile to different assembly code, but I'm trying to understand how the code might act differently. I understand that string literals are thrown into read only memory and are effectively static, but how does that differ from the explicit static below?

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

struct Obj1
{
    void Foo()
    {
        const char* str( "hello" );
    }
};

and

struct Obj2
{
    void Foo()
    {
        static const char* str( "hello" );
    }
};

回答by johannes

With your static version there will be only one variable which will be stored somewhere and whenever the function is executed the exact same variable will be used. Even for recursive calls.

对于您的静态版本,将只有一个变量将存储在某处,并且无论何时执行该函数,都将使用完全相同的变量。即使是递归调用。

The non-static version will be stored on the stack for every function call, and destroyed after each.

非静态版本将在每次函数调用时存储在堆栈中,并在每次调用后销毁。

Now your example is a bit complicated in regards to what the compiler actually does so let's look at a simpler case first:

现在,您的示例在编译器实际执行的操作方面有点复杂,因此让我们先看一个更简单的情况:

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

And then a main something like this:

然后是这样的主要内容:

int main() {
    foo();
    foo();
    return 0;
}

will print

将打印

3
2

whereas with

而与

void foo() {
    long i = 4;
    --i;
    printf("%l\n", i);
}

it will print

它会打印

3
3

Now with your example you have a const, so the value can't be changed so the compiler mightplay some tricks, while it often has no effect on the code generated, but helps the compiler to detect mistakes. And then you have a pointer, and mind that the static has effects on the pointer itself, not on the value it points to. So the string "hello" from your example will most likely be placed in the .data segment of your binary, and just once and live as long as the program lives,independent from the static thing .

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

回答by sbi

A local static variable is initialized the first timeits definition is encountered, but not destructedwhen the function exits. So it keeps its valuebetween invocations of the function.

局部静态变量在第一次遇到它的定义初始化,但在函数退出时不会被破坏。因此它在函数调用之间保持其值

In case of a constthis is not all that helpful - at least, as long as constructing the constant value is as neglectable performance-wise as the assignment of an address. (If the constobject is not a constant expression, or the expression takes considerable resources to create - like in const Foo bar = foobar();, where foobar()can take considerable time -, the difference might become important.)

在 a 的情况下,const这并不是那么有用 - 至少,只要构造常量值在性能方面与地址分配一样可忽略不计。(如果const对象不是常量表达式,或者表达式需要大量资源来创建 - 比如 in const Foo bar = foobar();, wherefoobar()可能需要大量时间 - ,差异可能变得重要。)

Where it does make a difference is when you want to return the object per reference or pointer: You cannot return a reference or pointer to a local object, unless it is a local static object. (Thanks to Matthieu for pointing this out.) However, when you want to use this you need to keep in mind that local statics are inherently thread-unsafe.

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

回答by Thomas Matthews

I have found out that some compilers treat the two differently.

我发现有些编译器对两者的处理方式不同。

The version with const char *will copy data from a read-only location to a variable on the stack.

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

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

static const char *引用只读位置数据的版本(不执行复制)。

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.

我在使用调试器单步执行函数的汇编代码时发现了这种差异。我建议您要么打印出汇编代码,要么在汇编语言级别使用调试器逐一查找确切的事实

回答by JoeG

While there is a technical difference, in terms of usage and effect your two examples are identical.

虽然存在技术差异,但在用法和效果方面,您的两个示例是相同的。

In more detail, your use of the statickeyword applies to the pointer to the string literal, not to the string literal itself. The pointer in example 1 will be placed on the stack, the pointer in example two will be placed with the static variables.

更详细地说,您对static关键字的使用适用于指向字符串文字的指针,而不是字符串文字本身。示例 1 中的指针将放置在堆栈中,示例 2 中的指针将与静态变量一起放置。

I'd be suprised if they don't both get optimized to the same thing though.

不过,如果他们都没有针对同一件事进行优化,我会感到惊讶。