c++ - 确定类静态变量的总大小?

标签 c++ class c++11 static sizeof

在 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/

相关文章:

c++ - 模板类可以指向彼此的实例吗?

c++ - 为什么要用友元函数来定义比较运算符?

c# - 使用 C# 访问另一个域中的一个域类文件

c++ - C++11中私有(private)继承聚合类的类的聚合初始化

c++ - 创建模板函数以使用该函数参数调用其他函数

c++ - 指向 lambda 的智能指针

c++ - 模板偏特化

c++ - 可变长度数组性能影响 (C/C++)

c++ - 将模板化的 C++ 类拆分为 .hpp/.cpp 文件——这可能吗?

C++ 类定义。属性作为指针?哪个是正确的方法?