2014-03-05 14 views
3

标准C(ISO/IEC 9899:1999)第6.5.3.4说为什么标准者禁用的sizeof要被施加到功能

sizeof运算符不应被应用于具有 功能型或表达不完整的类型

但是为什么? 使用readelf检查可执行文件显示,在编译过程中函数的大小完全知道。

Symbol table '.symtab' contains 67 entries: 
    Num: Value   Size Type Bind Vis  Ndx Name 
....... 
    37: 0000000000400541 16 FUNC LOCAL DEFAULT 13 clean 
....... 
    46: 00000000004005f0  2 FUNC GLOBAL DEFAULT 13 __libc_csu_fini 
...... 
    49: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBC_2.2.5 
    52: 00000000004005f4  0 FUNC GLOBAL DEFAULT 14 _fini 
    53: 0000000000000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBC_ 
ed 
    58: 0000000000400560 137 FUNC GLOBAL DEFAULT 13 __libc_csu_init 

    62: 000000000040052c 21 FUNC GLOBAL DEFAULT 13 main 

这里大小0属于功能从共享库,[email protected]@GLIBC_2.2.5功能例如。所以,我检查libc信息,这里涉及到[email protected]@GLIBC_2.2.5

      Size Type 
    ........... 
    399: 0000000000070ec0 392 FUNC WEAK DEFAULT 12 [email protected]@GLIBC_2.2.5 

一块readelf -a /lib/x86_64-linux-gnu/libc.so.6输出的是它根本不需要的特征,或者它打破C理念,还是有,我不能看到一些技术问题?

+0

如果函数内联,该怎么办?你如何计算它的大小? –

回答

4

我认为这是因为sizeof只对对象有意义,对象的表示形式为unsigned char [sizeof(type)]。现在在C中,函数没有表示(没有从函数指针类型到数据指针类型的转换),所以你可以说没有有用的sizeof

2

使用readelf检查可执行文件显示在编译过程中函数大小完全知道。

但是,如果你在同一个系统,或用不同的优化选项,即使相同的编译器上编译不同的编译器代码,这个大小通常changes.For例如,如果您使用的是gcc,尝试用gcc -O0编译代码和gcc -O2,然后比较你的函数的代码大小。

但编译器做出的优化不会改变他们尝试优化的代码的行为。并且让一个表达式在不同的优化级别下具有不同的值正在改变代码的行为。汇编器和/或链接器也可以对由编译器生成的汇编代码进行一些优化或修改,因此改变了一些函数的代码大小。另外,C不是一种函数式编程语言,函数不是一类对象,这意味着你不能将它存储到一个变量中,将它作为参数传递给另一个函数,等等,这似乎毫无意义获取函数的大小。

+0

这就是为什么我检查在编译期间是否知道函数大小。他们是已知的。如果编译期间已知的大小,sizeof可以返回当前编译中函数的大小,并带有当前优化级别。 – Dabo

+0

但编译器进行的优化不会改变他们尝试优化的代码的行为。并且让一个表达式在不同的优化级别下具有不同的值,正在改变代码的行为。 –

+2

编译器不知道函数的最后大小,因为它可能在链接时更优化 –

1

C的要点是它对指令进行了抽象,所以你不必处理程序的二进制表示。与汇编相比,这提供了许多优势 - 主要是提高了生产力,便携性。

由于无论如何您都无法访问数据或复制数据等,因此sizeof功能并不会有用。系统可将可执行内存标记为仅执行,因此需要C标准你能够做到这些事情不能在这样的系统上实施。

编译会困难得多。它基本上需要一个单独的通行证,在完成所有事情之后,通过填写函数的大小来回头。这就是说,这将是一个可笑的真棒功能,你可以检查是否(sizeof(*函数)== 0),看看它是否内联,等等。但是,考虑到c99并没有真正实现到处都是,即使在最好的情况下,我也会说,它不会在2050年之前提供。

+0

我认为这对于不同的逆向工程任务可能有用,也许它可能对小型嵌入式系统有用。但这只是一种猜测,实际上我从来不需要知道功能的大小。 – Dabo