在 C++ 中,我可以使用 sizeof(my_class)
确定类对象的大小。
但是,类的静态部分似乎没有等效的运算符。
C++ 中是否有类似sizeof(static my_class)
的东西?
最佳答案
您不会在标准 C++ 中找到合法或可移植的1 方法来执行此操作,但您当然可以使用特定于平台的工具来检查二进制文件以获得全局大小的估计数据。
在 Unix 平台上,您可以使用多种 ELF 格式阅读工具中的一种来转储符号表和大小。例如,像这样的东西:
nm --demangle --print-size a.out | egrep -i ' [bdgsr] '
将转储 .bss
、 .data
、 .rodata
和相关部分2 中所有全局数据的大小(作为输出中的第二个字段)。
--demangle
参数为您提供来自 C++ 错位名称的人类可读名称。管道末尾的 egrep
将符号限制为通常用于静态变量的符号(即,它省略了函数的符号)。给定以下类(class):
class Foo {
static void StaticFunction();
void MemberFunction();
static int some_int_s;
static long some_zero_long;
static char some_char_array[];
static const char *some_const_string;
};
int Foo::some_int_s = 5;
char Foo::some_char_array[42];
const char* Foo::some_const_string = "hello, world?";
void Foo::StaticFunction() {
}
void Foo::MemberFunction() {
static double f = 0.5;
}
...并使用 g++
编译,上面给出的 nm
命令输出:
0000000000000000 0000000000000004 D Foo::some_int_s
0000000000000000 000000000000002a B Foo::some_char_array
0000000000000008 0000000000000008 D Foo::some_const_string
0000000000000010 0000000000000008 d Foo::MemberFunction()::f
第二列是全局的大小:int
为 4 字节,char[]
为 0x2a (42) 字节,依此类推。请注意,它也包括函数局部静态变量,这可能是您想要的,因为它们像其他任何东西一样占用大小。您可以使用另一个 grep
来限制特定类。
请注意,Foo::some_const_string
的大小为 8,尽管 hello, world?
的值为 14 个字符(包括终止空值)。事实上,您会发现任何 const char *
或任何静态指针在 64 位平台上的大小都是 8,因为这是指针本身的大小。 字符串文字(字符 h,e,l,l,o,...
)的实际数据存储在其他地方,并且 nm
不报告此大小。一般来说,确定字符串文字的大小 is complex 可能没有直接的答案(即,几个类可能共享相同的底层文字数据)。如果您真的想将它包含在您的会计中,您可能必须编写类似 readelf
的脚本。
您也可以尝试现有的二进制大小调整实用程序,例如 Bloaty McBloatface ,尽管快速浏览自述文件似乎表明它可能只是提供与上述相同的信息(例如,它似乎无法处理“字符串文字”问题)。
1 例如,a comment 提到了一种在运行时采用“第一个”和“最后一个”静态变量的差异来估计大小的方法,但除了未定义的行为 它不太可能在实践中工作,因为全局变量分布在二进制文件的各个部分,例如 .bss
、 .data
、 .rodata
和它们的其他变体,因此对于许多人来说,简单的减法几乎肯定会返回错误的结果类。
2 特别是,当我说“相关”时,我的意思是除了默认部分之外,它还会转储“小”已初始化和未初始化部分的大小。
关于c++ - 确定类静态变量的总大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45697799/