gpt4 book ai didi

c++ - 自由函数中静态变量与静态成员函数的区别

转载 作者:可可西里 更新时间:2023-11-01 18:35:34 25 4
gpt4 key购买 nike

我有这样的代码:

struct Storage
{
static int GetData()
{
static int global_value;
return global_value++;
}
};
int free_func()
{
static int local_value;
return local_value++;
}

int storage_test_func()
{
return Storage::GetData();
}

在 OSX 上编译它:

$ clang++ 1.cpp -shared

并运行 nm:

$ nm | c++filt

我得到了奇怪的结果:

0000000000000f50 T storage_test_func()
0000000000000f30 T free_func()
0000000000000f60 unsigned short Storage::GetData()
0000000000001024 bool free_func()::local_value
0000000000001020 D Storage::GetData()::global_value
U dyld_stub_binder

两个符号(local_valueglobal_value)有不同的链接!一个明显的区别是 global_value 是在静态成员函数中定义的,而 local_value 是在自由函数中定义的。

有人能解释一下为什么会这样吗?

更新:

阅读评论后,我似乎应该澄清一些事情。也许使用 c++filt 是个坏主意。没有它显示:

$ nm

0000000000000f50 T __Z17storage_test_funcv
0000000000000f30 T __Z9free_funcv
0000000000000f60 t __ZN7Storage7GetDataEv
0000000000001024 b __ZZ9free_funcvE11local_value
0000000000001020 D __ZZN7Storage7GetDataEvE5value
U dyld_stub_binder

是的。 __ZZ9free_funcvE11local_value 转到 BSS,__ZZN7Storage7GetDataEvE5value 转到数据部分。

man nm 说:

If the symbol is local (non-external), the symbol's type is instead represented by the corresponding lowercase letter.

这就是我所看到的。 __ZZ9free_funcvE11local_value用小写b标记,__ZZN7Storage7GetDataEvE5value用大写D标记。

这是问题的主要部分。为什么会这样?

UPD2另一种方式:

$ clang++ -c -emit-llvm  1.cpp
$ llvm-dis 1.bc

显示这些变量在内部是如何表示的:

@_ZZ9free_funcvE11local_value = internal global i32 0, align 4
@_ZZN7Storage7GetDataEvE5value = global i32 0, align 4

UPD3

还有一些关于符号所属的不同部分的担忧。将 __ZZ9free_funcvE11local_value 放入文本部分不会改变其可见性:

struct Storage
{
static int GetData()
{
static int value;
return value++;
}
};


int free_func()
{
static int local_value = 123;
return local_value++;
}

int storage_test_func()
{
return Storage::GetData();
}

编译:

$ clang++ 1.cpp -shared

检查:

$ nm

给予:

0000000000000f50 T __Z17storage_test_funcv
0000000000000f30 T __Z9free_funcv
0000000000000f60 t __ZN7Storage7GetDataEv
0000000000001020 d __ZZ9free_funcvE11local_value
0000000000001024 D __ZZN7Storage7GetDataEvE5value

现在两个符号都在数据部分,但仍然其中一个是本地,另一个是全局。问题是为什么会发生?有人可以了解此类编译器决策的逻辑吗?

最佳答案

静态成员函数中的局部静态变量与自由函数中的局部静态变量没有区别。

Two symbols (local_value and global_value) have different linkage!

在标准命名法中,从标准的角度来看,这两个变量没有联系。

函数之间的相关区别不在于一个是静态成员函数而另一个不是。相关的区别是前者是一个内联函数,而后者不是。

非内联函数只能在一个翻译单元中定义,因此它们的局部静态变量不需要从其他翻译单元访问。

另一方面,内联函数必须在使用它们的每个翻译单元中定义。而且,由于局部静态必须在全局范围内引用同一个对象,因此该对象必须对多个翻译单元可见。

关于c++ - 自由函数中静态变量与静态成员函数的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36952516/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com