首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >函数内部的静态变量是如何工作的?

函数内部的静态变量是如何工作的?
EN

Stack Overflow用户
提问于 2011-10-12 13:23:16
回答 3查看 3.1K关注 0票数 15

在以下代码中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int count(){
    static int n(5);
    n = n + 1;
    return n;
}

变量n仅在第一次调用函数时实例化一次。

应该有一个标志或其他东西,以便它只初始化变量一次。我试着查看从gcc那里生成的汇编代码,但没有任何线索。

编译器是如何处理这个问题的?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-12 13:30:43

当然,这是特定于编译器的。

在生成的程序集中看不到任何检查的原因是,由于n是一个int变量,g++只是将其视为一个预初始化为5的全局变量。

让我们看看如果我们对std::string执行同样的操作会发生什么

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <string>

void count() {
    static std::string str;
    str += ' ';
}

生成的程序集如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
_Z5countv:
.LFB544:
        .cfi_startproc
        .cfi_personality 0x3,__gxx_personality_v0
        .cfi_lsda 0x3,.LLSDA544
        pushq   %rbp
        .cfi_def_cfa_offset 16
        movq    %rsp, %rbp
        .cfi_offset 6, -16
        .cfi_def_cfa_register 6
        pushq   %r13
        pushq   %r12
        pushq   %rbx
        subq    $8, %rsp
        movl    $_ZGVZ5countvE3str, %eax
        movzbl  (%rax), %eax
        testb   %al, %al
        jne     .L2                     ; <======= bypass initialization
        .cfi_offset 3, -40
        .cfi_offset 12, -32
        .cfi_offset 13, -24
        movl    $_ZGVZ5countvE3str, %edi
        call    __cxa_guard_acquire     ; acquire the lock
        testl   %eax, %eax
        setne   %al
        testb   %al, %al
        je      .L2                     ; check again
        movl    $0, %ebx
        movl    $_ZZ5countvE3str, %edi
.LEHB0:
        call    _ZNSsC1Ev               ; call the constructor
.LEHE0:
        movl    $_ZGVZ5countvE3str, %edi
        call    __cxa_guard_release     ; release the lock
        movl    $_ZNSsD1Ev, %eax
        movl    $__dso_handle, %edx
        movl    $_ZZ5countvE3str, %esi
        movq    %rax, %rdi
        call    __cxa_atexit            ; schedule the destructor to be called at exit
        jmp     .L2
.L7:
.L3:
        movl    %edx, %r12d
        movq    %rax, %r13
        testb   %bl, %bl
        jne     .L5
.L4:
        movl    $_ZGVZ5countvE3str, %edi
        call    __cxa_guard_abort
.L5:
        movq    %r13, %rax
        movslq  %r12d,%rdx
        movq    %rax, %rdi
.LEHB1:
        call    _Unwind_Resume
.L2:
        movl    $32, %esi
        movl    $_ZZ5countvE3str, %edi
        call    _ZNSspLEc
.LEHE1:
        addq    $8, %rsp
        popq    %rbx
        popq    %r12
        popq    %r13
        leave
        ret
        .cfi_endproc

我用bypass initialization注释标记的那一行是条件跳转指令,如果变量已经指向一个有效的对象,它会跳过构造。

票数 18
EN

Stack Overflow用户

发布于 2011-10-12 13:26:42

这完全取决于实现;语言标准没有说明这一点。

在实践中,编译器通常会在某处包含一个隐藏的标志变量,用于指示静态变量是否已被实例化。静态变量和标志可能在程序的静态存储区(例如,数据段,而不是堆栈段),而不是在函数作用域内存中,因此您可能需要在程序集中查找。(由于显而易见的原因,该变量不能放在调用堆栈中,因此它实际上就像一个全局变量。“静态分配”实际上涵盖了所有类型的静态变量!)

更新:正如@aix指出的那样,如果将静态变量初始化为常量表达式,您甚至可能不需要标志,因为初始化可以在加载时执行,而不是在第一次函数调用时执行。与C++03相比,在C++11中应该能够更好地利用这一点,这要归功于常量表达式的更广泛可用性。

票数 7
EN

Stack Overflow用户

发布于 2011-10-12 13:27:37

这个变量很可能会像普通的全局变量一样由gcc来处理。这意味着初始化将直接在二进制文件中静态初始化。

这是可能的,因为你用一个常量来初始化它。如果你初始化了它,例如。对于另一个函数返回值,编译器将添加一个标志,并根据该标志跳过初始化。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7740761

复制
相关文章
LinkedHashSet内部是如何工作的(翻译)
LinkedHashSet是HashSet的一个“扩展版本”,HashSet并不管什么顺序,不同的是LinkedHashSet会维护“插入顺序”。HashSet内部使用HashMap对象来存储它的元素,而LinkedHashSet内部使用LinkedHashMap对象来存储和处理它的元素。这篇文章,我们将会看到LinkedHashSet内部是如何运作的及如何维护插入顺序的。
用户3579639
2018/10/22
1K0
LinkedHashSet内部是如何工作的(翻译)
c语言局部变量、全局变量、静态变量、内部函数、外部函数、声明、定义、extern作用总结
  前两种方式定义的变量可以在函数内任何地方使用,而第三种方式定义的变量只能在复合语句内使用。
vv彭
2020/10/27
10K0
c语言局部变量、全局变量、静态变量、内部函数、外部函数、声明、定义、extern作用总结
PHP递归函数内的静态变量
作者:matrix 被围观: 3,689 次 发布时间:2015-06-20 分类:兼容并蓄 零零星星 | 一条评论 »
HHTjim 部落格
2022/09/26
1.2K0
JavaScript 是如何工作: Shadow DOM 的内部结构+如何编写独立的组件!
Web Components 是一套不同的技术,允许你创建可重用的定制元素,它们的功能封装在你的代码之外,你可以在 Web 应用中使用它们。
前端小智@大迁世界
2019/01/29
1.8K0
JavaScript 是如何工作: Shadow DOM 的内部结构+如何编写独立的组件!
静态变量 静态对象 静态函数和非静态函数的区别。(我的理解,大家看看对不对)
先明确一下 语言:asp.net C# 1、静态变量: static string str1 = "1234"; 2、静态对象 static SqlConnection cn = new SqlConnection(); 3、静态函数 class aa {     public static string test(string str)     {         return str & "111";     } } 调用 aa.test("123"); 4、非静态函数(就是需要实例化的) cla
用户1174620
2018/02/07
1.8K0
Spring Boot 注入外部配置到应用内部的静态变量
至此,即可在 Spring Boot 全局任意引用 StaticProperties.CUSTOM_NAME
轻量级云原生架构实验室
2018/08/02
8360
java内部类和静态内部类区别_静态内部类对象的创建
在阅读Java Collection Framwork时,LinkedList中有个静态内部类:
全栈程序员站长
2022/11/10
6590
Spring Boot 注入外部配置到应用内部的静态变量
Spring Boot允许你外部化你的配置,这样你就可以在不同的环境中使用相同的应用程序代码,你可以使用properties文件、YAML文件、环境变量和命令行参数来外部化配置,属性值可以通过使用@Value注解直接注入到你的bean中,通过Spring的Environment抽象访问,或者通过@ConfigurationProperties绑定到结构化对象。那么如何进行Spring Boot 注入外部配置到应用内部的静态变量呢?操作如下:
码农小胖哥
2019/12/10
1.2K0
什么是全局变量,局部变量,静态全局变量,静态局部变量
这些是编程语言中的基本概念,如果你还不是非常明确地清楚标题的问题,并且不知道作用域,链接属性,存储期等概念的具体含义,那么本文你不该错过。为了更加清晰的理解我们的问题,需要先了解三个概念:作用域,链接属性,存储期。
编程珠玑
2019/07/12
2.5K0
java静态内部类和非静态内部类的区别_静态内部类有什么问题
1、变量和方法不能声明为静态的。(类的编译顺序:外部类–静态方法或属性–内部类,如果内部类声明为静态的,造成编译顺序冲突。个人理解)
全栈程序员站长
2022/11/07
6450
java静态变量加载顺序_内部类为什么不能有静态
我们声明一个类,这个类有个内部静态类。还有主函数,当我们启动程序之后,运行java application程序。
全栈程序员站长
2022/11/07
4130
java静态变量加载顺序_内部类为什么不能有静态
Widget是如何工作的
在前面我们介绍各种各样的Widget,相信大家对Wiget的使用都已经有了自己的认识,今天我们就从底层角度看下Widget是如何工作,是什么支撑起了Wiget这个系统。
flyou
2020/05/28
3.3K0
Goroutine是如何工作的
一、Go语言简介 如果你是Go语言新手,或如果你对"并发(Concurrency)不是并行(parallelism)"这句话毫无赶脚,那么请看一下Rob Pike大神关于这个主题的演讲吧,演讲共30分 钟,我敢保证你在这个演讲上花费30分钟是绝对值得的。 总结一下两者(Concurrency和Parallelism)的不同:"当人们听到并发(Concurrency)这个词时,总是会想起并行 (Parallelism),它们之间有相关性,但却是两个明显不同的概念。在编程领域,并发(Concurrency)是独
李海彬
2018/03/21
2.2K0
HTTPS是如何工作的
大家在浏览网页的时候一定有这样的体验,有一些网站在网址那里会显示一个绿色的挂锁,并且网址中“https”相关的字样也是绿色的,聪明的朋友肯定会问,这些颜色和符号代表什么意思呢?想想大家在上网的时候,经常要输入账号和密码,有时候网购还要输入信用卡信息,如果这些信息被偷了,后果是很严重的。是的,这个绿色的锁就是用来保护大家的信息不被黑客窃取。现在很多网站默认使用HTTPS来保护用户的信息,截止2018年4月,Alexa前100万的网站中,32.2%使用HTTPS作为默认设置,互联网最受欢迎的137971个网站中,57.1%使用了HTTPS;Firefox遥测数据显示,70%的网站使用了HTTPS。
大蟒传奇
2018/07/31
2.4K0
HTTPS是如何工作的
JavaScript是如何工作的?
当将 JavaScript 文件加载到浏览器中时,JavaScript Engine 会从上到下逐行执行该文件(异步代码将是一个例外,我们将在本系列后面的内容中看到异步代码)。
小丑同学
2020/10/30
2.8K0
JavaScript是如何工作的?
TypeScript是如何工作的
TypeScript 是一门基于 JavaScript 拓展的语言,它是 JavaScript 的超集,并且给 JavaScript 添加了静态类型检查系统。TypeScript 能让我们在开发时发现程序中类型定义不一致的地方,及时消除隐藏的风险,大大增强了代码的可读性以及可维护性。相信大家对于如何在项目中使用 TypeScript 已经轻车熟路,本文就来探讨简单探讨一下 TypeScript 是如何工作的,以及有哪些工具帮助它实现了这个目标。
ConardLi
2021/09/29
5.5K0
TypeScript是如何工作的
HashMap是如何工作的
最简单形式的 hash,是一种在对任何变量/对象的属性应用任何公式/算法后, 为其分配唯一代码的方法。
java思维导图
2020/06/05
3.9K0
HashMap是如何工作的
Goroutine是如何工作的
在golangweekly的第36期Go Newsletter中我发现一篇短文"How Goroutines Work" ,其作者在参考了诸多资料后,简短概要地总结了一下 Goroutine的工作原理,感觉十分适合刚入门的Gophers(深入理解Goroutine调度的话,可以参考Daniel Morsing的" The Go scheduler" )。这里粗译如下。 一、Go语言简介 如果你是Go语言新手,或如果你对"并发(Concurrency)不是并行(parallelism)"这句话毫无赶脚,那么请
李海彬
2018/03/19
2.3K0
JavaScript 是如何工作的🔥 🤖 [视觉解释]
JavaScript 是世界上最受欢迎和最讨厌的语言之一。它被爱,因为它是有效的。您只需学习 JavaScript 即可制作全栈应用程序。它也被讨厌,因为它以出乎意料和令人不安的方式行事,如果您不投入理解该语言,可能会让您讨厌它💔。 这篇博客将解释 JavaScript 如何在浏览器中执行代码,我们将通过动画 gif 来学习它😆。看完这篇博文,你离成为Rockstar开发者又近了一步🎸😎 执行上下文 “ JavaScript 中的一切都发生在一个执行上下文中。” 我希望每个人都记住这句话,因为它是必不可
玖柒的小窝
2021/09/12
2.6K0
JavaScript 是如何工作的🔥 🤖 [视觉解释]
Java内部类是如何实现的
本代码主要想说明的是作为内部类的TimePrinter可以直接访问外部类TalkingClock的私有成员变量beep。
Ryan-Miao
2019/05/17
7430

相似问题

静态同步函数是如何工作的?

30

lambda函数对象中的静态变量是如何工作的?

50

静态构造函数是如何工作的?

1060

静态函数是如何工作的?

72

getObject函数是如何内部工作的?

210
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文