草庐IT

c++ - 寻找有关静态和内联函数的说明

coder 2023-11-17 原文

最初,我认为 staticinline 对函数的含义如下:


警告:这是我过去的想法,不要认为这是正确的。


static 函数只存在一次。所有使用它的东西都使用相同的功能。*

inline 函数的内容大概被复制到调用函数中。编译器实际上可能会忽略这一点,但对于非模板头文件中的定义,它们有必要避免重复定义。

static inline 函数,我还没弄明白那是什么意思。

*请注意,类模板有效地生成类,因此它们的静态内容对于每个派生类型是完全不同的。


我从 C++ for Java Programmers(Mark Allen Weiss,ISBN 0-13-919424-X)这本书中得到了这种印象。在第 2.1.6 段,它说:

In some situations, the overhead of making a function call can be significant. For instance, the max2 routine is trivial, and so one might be tempted to simply replace the function invocation in main with the code that max2 is logically performing: ... Of course, this would be sacrificing good programming practice for speed.

To avoid this one can use the inline directive. The inline directive suggests to the compiler that it should generate code that avoids the overhead of a function definition ...

令人惊讶的是,我找不到任何关于static 函数的信息。它可能在那里,但我在索引中找不到它。


但后来我发现this answer ,这似乎声称完全相反:

The non-static inline function declaration refers to the same function in every translation unit (source file) that uses it.

If it is static then each TU has its own version of the function and hence its own copy of the static local variables.


This answer似乎对 inline 的含义采取不同的立场,同意我原来的解释:

inline conveys exactly what you want: "please suppress the ODR rule for this function, so that each translation unit can (and must) supply its own copy of the function's definition".

但是接着说 inline 函数可以被内联(我假设这意味着复制到调用它的每个地方)或合并在一起。

The compiler will then either inline calls to the function, or merge together the function definitions from different TU's (so that the resulting function exists once in the executable).

然后它还说声明一个函数 static 意味着将存在任意数量的函数:

static, on the other hand, tells the compiler to generate the function in every translation unit where it is defined, and just not share it. So you end up with an arbitrary number of technically separate functions existing in the resulting executable.


我不确定,但听起来 static 函数不止一次存在,而 inline 函数在编译器实际执行内联时只存在一次。这与我过去的想法完全相反。

但最重要的是,这里有一堆关于单例的问题,其中每个 getInstance 函数都被声明为 static:

所以如果 static 函数真的可以存在不止一次,这实际上意味着会有多个本地 static 单例对象,我见过的每个 C++ 单例示例都会是错误的,这似乎不太可能。

我不明白了。一切似乎都在暗示着别的东西。 staticinline 以及作为奖励的:static inline 对函数来说真的意味着什么?

最佳答案

inline 很容易解释。 inline 基本上是对编译器的提示,即应该将给定的函数复制(内联)到调用它的任何函数中,而不是进行正常的函数调用。对于简短的简单函数,这消除了函数调用开销。

编译器不需要遵守inline:如果它认为内联不值得额外的代码量(这会导致缓存未命中并增加代码大小),它可以选择生成一个普通函数).

inline 函数仅在声明它们的源文件中可用。因此,旨在广泛重用的内联函数通常放在头文件中。


static 在 C++ 中有很多不同的用途:

  • static 类方法或成员本质上属于类而不是类的任何特定实例,如 Java 的 static。这适用于静态方法和静态变量。请注意,静态类成员只有一个拷贝,即使您将声明放在共享头文件中也是如此;定义只能在一个文件中(static const 成员除外)
  • static 全局函数或变量只能由定义它的编译单元(源文件)访问。这样,它有点像一个内联函数,编译器可能会选择内联一个静态函数。要共享的静态函数也放在头文件中。
  • 函数内的 static 局部变量是在该函数的所有调用中都存在的变量,但只能在该函数内部访问(不同于局部变量,局部变量对于特定的调用是私有(private)的)函数)。

关于c++ - 寻找有关静态和内联函数的说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24170568/

有关c++ - 寻找有关静态和内联函数的说明的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  3. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  4. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  5. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  6. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  7. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  8. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  9. spring.profiles.active和spring.profiles.include的使用及区别说明 - 2

    转自:spring.profiles.active和spring.profiles.include的使用及区别说明下文笔者讲述spring.profiles.active和spring.profiles.include的区别简介说明,如下所示我们都知道,在日常开发中,开发|测试|生产环境都拥有不同的配置信息如:jdbc地址、ip、端口等此时为了避免每次都修改全部信息,我们则可以采用以上的属性处理此类异常spring.profiles.active属性例:配置文件,可使用以下方式定义application-${profile}.properties开发环境配置文件:application-dev

  10. ruby-on-rails - 将字符串转换为 ruby​​-on-rails 中的函数 - 2

    我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。

随机推荐