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

时间:2017-08-15 17:02:03

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

在C ++中,我可以使用sizeof(my_class)来确定类对象的大小。

但是,类的静态部分似乎没有等效运算符。

C ++中有sizeof(static my_class)之类的内容吗?

1 个答案:

答案 0 :(得分:2)

您无法在标准C ++中找到合法或便携的 1 方法,但您当然可以使用特定于平台的工具来检查二进制文件以估算大小全球数据。

在Unix平台上,您可以使用各种ELF格式的阅读工具之一来转储符号表以及大小。例如,像:

nm --demangle --print-size a.out | egrep -i ' [bdgsr] '

将转储.bss.data.rodata及相关部分 2 。

--demangle参数为您提供C ++错位名称中的可读名称。管道末端的egrep将符号限制为通常用于静态变量的符号(即,它省略了函数的符号)。鉴于以下课程:

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,尽管对自述文件的快速扫描似乎表明它可能只是提供与上面相同的信息(例如,它没有&#t; t似乎处理"字符串文字"问题。

1 例如,a comment提到了一种方法来区分"第一"和"最后"在运行时静态估计大小,但除了未定义的行为之外,它不可能在实践中工作,因为全局变量分布在二进制文件的各个部分,例如{{1 }},.bss.data以及其他变体,因此简单的减法几乎肯定会为许多类返回错误的结果。

2 特别是,当我说"相关"我的意思是它倾倒了"小"的大小。初始化和未初始化的部分以及默认部分。