【问题标题】:C: Uninitialized int type size bigger then must beC:未初始化的 int 类型大小必须大于
【发布时间】:2017-09-02 16:32:48
【问题描述】:

未初始化的int 变量will 被放置到.bss 部分。

但如果我添加这样一个变量 - size 的结果中的 bss 部分长度变得更大,变为 8 个字节而不是 4 个 - 为什么会这样?

这是一个例子:

一个未初始化的整数:

#include <stdio.h>

int a;
//int b;

int main () {

    printf("A size: %d\n", sizeof(a));
//    printf("B size: %d\n", sizeof(b));
    return 0;

}

size 的结果:

$ gcc int_szie.c -o int_szie
$ size int_szie
   text    data     bss     dec     hex filename
   1483     536       8    2027     7eb int_szie

取消注释 b var - 现在 bss 是 16 个字节:

...
int a;
int b;

int main () {

    printf("A size: %d\n", sizeof(a));
    printf("B size: %d\n", sizeof(b));
    return 0;
...
$ gcc int_szie.c -o int_szie
$ size int_szie                                                                                                                                                     
   text    data     bss     dec     hex filename                                                                                                                                                                                              
   1628     592      16    2236     8bc int_szie

sizeof() 结果:

$ ./int_szie                                                                                                                                                                     
A size: 4                                                                                                                                                                                                                                     
B size: 4

我什至不敢问为什么data 部分在整个 56 个字节上变得更大:

数据 536

对比:

数据 592

gcc:

$ gcc --version
gcc (GCC) 7.1.1 20170630

【问题讨论】:

  • 为避免因使用不匹配的说明符/类型(即 UB)而分心,请使用 printf("A size: %zu\n", sizeof(a));printf("A size: %d\n", (int) sizeof(a));

标签: c linux gcc


【解决方案1】:

我运行了相同的代码,只是添加了long long b。代码如下所示:

#include <stdio.h>

 int a;
 long long b;

 int main () {

     printf("A size: %d\n", sizeof(a));
     //    printf("B size: %d\n", sizeof(b));
         return 0;

 }

objdump 输出如下:

mdeore@mdeore-Lenovo:~$ objdump -t ./a.out

./a.out:     file format elf64-x86-64

SYMBOL TABLE:
0000000000400238 l    d  .interp    0000000000000000              .interp
0000000000400254 l    d  .note.ABI-tag  0000000000000000              .note.ABI-tag
0000000000400274 l    d  .note.gnu.build-id 0000000000000000              .note.gnu.build-id
0000000000400298 l    d  .gnu.hash  0000000000000000              .gnu.hash
00000000004002b8 l    d  .dynsym    0000000000000000              .dynsym
0000000000400318 l    d  .dynstr    0000000000000000              .dynstr
0000000000400358 l    d  .gnu.version   0000000000000000              .gnu.version
0000000000400360 l    d  .gnu.version_r 0000000000000000              .gnu.version_r
0000000000400380 l    d  .rela.dyn  0000000000000000              .rela.dyn
0000000000400398 l    d  .rela.plt  0000000000000000              .rela.plt
00000000004003c8 l    d  .init  0000000000000000              .init
00000000004003f0 l    d  .plt   0000000000000000              .plt
0000000000400420 l    d  .plt.got   0000000000000000              .plt.got
0000000000400430 l    d  .text  0000000000000000              .text
00000000004005c4 l    d  .fini  0000000000000000              .fini
00000000004005d0 l    d  .rodata    0000000000000000              .rodata
00000000004005e0 l    d  .eh_frame_hdr  0000000000000000              .eh_frame_hdr
0000000000400618 l    d  .eh_frame  0000000000000000              .eh_frame
0000000000600e10 l    d  .init_array    0000000000000000              .init_array
0000000000600e18 l    d  .fini_array    0000000000000000              .fini_array
0000000000600e20 l    d  .jcr   0000000000000000              .jcr
0000000000600e28 l    d  .dynamic   0000000000000000              .dynamic
0000000000600ff8 l    d  .got   0000000000000000              .got
0000000000601000 l    d  .got.plt   0000000000000000              .got.plt


0000000000601028 l    d  .data  0000000000000000              .data
0000000000601038 l    d  .bss   0000000000000000              .bss
0000000000000000 l    d  .comment   0000000000000000              .comment
0000000000000000 l    df *ABS*  0000000000000000              crtstuff.c
0000000000600e20 l     O .jcr   0000000000000000              __JCR_LIST__
0000000000400460 l     F .text  0000000000000000              deregister_tm_clones
00000000004004a0 l     F .text  0000000000000000              register_tm_clones
00000000004004e0 l     F .text  0000000000000000              __do_global_dtors_aux


0000000000601038 l     O .bss   0000000000000001              completed.7585
0000000000600e18 l     O .fini_array    0000000000000000              __do_global_dtors_aux_fini_array_entry
0000000000400500 l     F .text  0000000000000000              frame_dummy
0000000000600e10 l     O .init_array    0000000000000000              __frame_dummy_init_array_entry
0000000000000000 l    df *ABS*  0000000000000000              abc.c
0000000000000000 l    df *ABS*  0000000000000000              crtstuff.c
0000000000400708 l     O .eh_frame  0000000000000000              __FRAME_END__
0000000000600e20 l     O .jcr   0000000000000000              __JCR_END__
0000000000000000 l    df *ABS*  0000000000000000
0000000000600e18 l       .init_array    0000000000000000              __init_array_end
0000000000600e28 l     O .dynamic   0000000000000000              _DYNAMIC
0000000000600e10 l       .init_array    0000000000000000              __init_array_start
00000000004005e0 l       .eh_frame_hdr  0000000000000000              __GNU_EH_FRAME_HDR
0000000000601000 l     O .got.plt   0000000000000000              _GLOBAL_OFFSET_TABLE_
00000000004005c0 g     F .text  0000000000000002              __libc_csu_fini
0000000000000000  w      *UND*  0000000000000000              _ITM_deregisterTMCloneTable
0000000000601028  w      .data  0000000000000000              data_start
0000000000601040 g     O .bss   0000000000000008              b       <<<<<<<< 'b' is 8 bytes
0000000000601038 g       .data  0000000000000000              _edata
00000000004005c4 g     F .fini  0000000000000000              _fini
0000000000000000       F *UND*  0000000000000000              printf@@GLIBC_2.2.5
0000000000000000       F *UND*  0000000000000000              __libc_start_main@@GLIBC_2.2.5
0000000000601028 g       .data  0000000000000000              __data_start
0000000000000000  w      *UND*  0000000000000000              __gmon_start__
0000000000601030 g     O .data  0000000000000000              .hidden __dso_handle
00000000004005d0 g     O .rodata    0000000000000004              _IO_stdin_used
0000000000400550 g     F .text  0000000000000065              __libc_csu_init
0000000000601050 g       .bss   0000000000000000              _end
0000000000400430 g     F .text  000000000000002a              _start
0000000000601048 g     O .bss   0000000000000004              a       <<<<<<<<< 'a' is 4 bytes
0000000000601038 g       .bss   0000000000000000              __bss_start
0000000000400526 g     F .text  000000000000001f              main
0000000000000000  w      *UND*  0000000000000000              _Jv_RegisterClasses
0000000000601038 g     O .data  0000000000000000              .hidden __TMC_END__
0000000000000000  w      *UND*  0000000000000000              _ITM_registerTMCloneTable
00000000004003c8 g     F .init  0000000000000000              _init

输出显示正确,int a 是 4 个字节,long long b 是 8 个字节。

size &lt;objfile&gt; 显示.bss 段的大小,而不是特定变量的大小。为了验证这个事实,从代码中删除 ab 全局变量,现在检查 .bss 段的大小,你仍然会看到大小为 8。

有类似的thread,在 Windows 操作系统上大小不同。

【讨论】:

    猜你喜欢
    • 2021-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多