我试图理解"static"修饰符在C中是如何工作的,我go 寻找它的含义,我发现的一切似乎都有点模糊.

它是一个修饰符,允许变量的值一直存在到程序执行结束.

我理解它的含义和用途,但除了这个定义之外,我还想了解它下面是如何工作的,所以我生成了C代码的汇编

char    *thing(char *a)
{
    char *b;

    b = malloc(3);

    b[0] = 'y';
    b[1] = '\0';
    return (b);
}

char    *some(int fd)
{
    static char *a = "happened";
    a = thing(a);
    return (a);
}

我用非静态a变量创建了另一个代码

/* With static variable */
    .file   "static_test.c"
    .text
    .globl  thing
    .type   thing, @function
thing:
.LFB6:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $32, %rsp
    movq    %rdi, -24(%rbp)
    movl    $3, %edi
    call    malloc@PLT
    movq    %rax, -8(%rbp)
    movq    -8(%rbp), %rax
    movb    $121, (%rax)
    movq    -8(%rbp), %rax
    addq    $1, %rax
    movb    $0, (%rax)
    movq    -8(%rbp), %rax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE6:
    .size   thing, .-thing
    .globl  some
    .type   some, @function
some:
.LFB7:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    %edi, -4(%rbp)
    movq    a.0(%rip), %rax
    movq    %rax, %rdi
    call    thing
    movq    %rax, a.0(%rip)
    movq    a.0(%rip), %rax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE7:
    .size   some, .-some
    .section    .rodata
.LC0:
    .string "happened"
    .section    .data.rel.local,"aw"
    .align 8
    .type   a.0, @object
    .size   a.0, 8
a.0:
    .quad   .LC0
    .ident  "GCC: (GNU) 12.1.0"
    .section    .note.GNU-stack,"",@progbits

/* no static variable */
    .file   "nostatic_test.c"
    .text
    .globl  thing
    .type   thing, @function
thing:
.LFB6:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $32, %rsp
    movq    %rdi, -24(%rbp)
    movl    $3, %edi
    call    malloc@PLT
    movq    %rax, -8(%rbp)
    movq    -8(%rbp), %rax
    movb    $121, (%rax)
    movq    -8(%rbp), %rax
    addq    $1, %rax
    movb    $0, (%rax)
    movq    -8(%rbp), %rax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE6:
    .size   thing, .-thing
    .section    .rodata
.LC0:
    .string "happened"
    .text
    .globl  some
    .type   some, @function
some:
.LFB7:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $32, %rsp
    movl    %edi, -20(%rbp)
    leaq    .LC0(%rip), %rax
    movq    %rax, -8(%rbp)
    movq    -8(%rbp), %rax
    movq    %rax, %rdi
    call    thing
    movq    %rax, -8(%rbp)
    movq    -8(%rbp), %rax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE7:
    .size   some, .-some
    .ident  "GCC: (GNU) 12.1.0"
    .section    .note.GNU-stack,"",@progbits

问题是,这两个汇编代码之间发生了什么以及它们之间的区别,以及它们在编译时和程序执行时的行为.

推荐答案

这可能是一个更好的例子.r具有本地作用域,但它不会位于堆栈的本地,而是位于中的.bss或.一个程序的数据段,只初始化一次为零.之后,对Rnd32的每次调用都将更新r.程序在每次调用时以固定顺序返回一个伪随机32位无符号整数,因此它是一个可重复的序列,遍历所有2^32个可能的值.

uint32_t Rnd32()
{
static uint32_t r = 0;
    r = r*1664525 + 1013904223;
    return r;
}

C++相关问答推荐

为什么macOS上的FIFA管道比匿名管道慢8倍?

带双指针的2D数组

sizeof结果是否依赖于字符串的声明?

Mise()在虚拟内存中做什么?

MISRA C:2012 11.3违规强制转换(FLOAT*)到(uint32_t*)

无效指针值在函数调用之间莫名其妙地改变

ATmega328P EEPROM未写入

拥有3x3二维数组并访问数组[1][3]等同于数组[2][0]?

进程已完成,退出代码为138 Clion

C-使用指针返回修改后的整数数组

将 struct 传递给函数

防止规范模式在C++中 echo 特殊字符

如何在VS 2022中正确安装额外的C头文件

Caesar密码调试:输出文本末尾的问号和随机字符

我正在try 将QSORT算法实现为C++中的泛型函数

如何在C中定义指向函数的指针并将该指针赋给函数?

生成一个半RNG,结果用C表示(无随机/随机)

当我在34mb的.mp4文件中使用FREAD时,我得到了一个分段错误,我如何解决它?

共享内存未授予父进程权限

将char*铸造为空**