【问题标题】:static variable in inline function [duplicate]内联函数中的静态变量[重复]
【发布时间】:2017-09-02 12:21:17
【问题描述】:

我对在多个翻译单元中调用以下内联函数时“幕后”究竟发生了什么感兴趣。

namespace some_name
{
    inline const float& get_float()
    {
        static const float a = 5.0f;
        return a;
    }
}

我的目的是创建一个外部链接变量“a”,它可以在代码中使用(如果包含名称空间的标头),但我也想防止对这个变量进行任何更改。从测试来看,我似乎成功了,但我对第一次调用此函数以及接下来的几次调用时究竟发生了什么感兴趣。

附加问题:我是否使用静态变量声明/定义污染了全局命名空间?

【问题讨论】:

  • 作为使函数返回静态 const float 的替代方法,为什么不将其作为类的成员变量,甚至是命名空间的成员变量;它仍然是常量...
  • UKMonkey 我不确定,如果我这样做,那么每次我在不同的翻译单元中使用变量时,我都会得到一个 const float 类型的副本。
  • 你确定a这种方式是外联的吗?为什么你甚至需要一个外部链接的常量?外部链接建议多个编译单元共享一个变量的一个实例,当它发生变化时,每个单元都会读取更新后的值。但预计常数不会改变。此外,在许多情况下,编译器会将常量值直接嵌入到指令中,这样它甚至不会出现在内存中。
  • 如果您有兴趣一探究竟,这里并不神秘。大多数编译器可以为您提供他们为此生成的代码的汇编级视图。

标签: c++ static inline inline-functions


【解决方案1】:

但我对第一次调用此函数以及接下来的几次调用时究竟发生了什么感兴趣。

初始化是静态的(在运行时不依赖任何东西),所以它可能在程序开始时执行。所有调用都只是返回对静态对象的引用。而且这些调用可能是内联扩展的,所以直接使用静态对象即可。

更简单的选择是在命名空间中使用全局变量。

附加问题:我是否使用静态变量声明/定义污染了全局命名空间?

没有。静态变量是本地的,因此不会污染任何命名空间。函数本身确实“污染”了声明它的命名空间。

【讨论】:

  • 命名空间中的static 变量会做相反的事情,即为每个包含标头的 TU 定义一个这样的变量。
  • @Quentin 是的,我的意思是一个全局变量(即具有静态存储的非局部变量)。不过,这对常量并不重要,因为来自不同编译单元的重复项无论如何都会被压缩,不是吗?
  • @Quentin 这正是我好奇的地方。这就是为什么我没有在命名空间中定义变量的原因。我想直接在包含这个头的所有 TU 中使用特定的一个静态对象。
  • @user2079303 不一定。这是关于 ODR 的使用,并且规则非常繁琐,但简而言之,当您获取常量的地址时,差异是显而易见的。使用单一定义(例如本地 staticextern 全局),所有 TU 的地址都相同,而使用 static 全局,则不是。
  • @user3271640 然后使用extern
猜你喜欢
  • 2010-09-16
  • 1970-01-01
  • 2016-04-27
  • 1970-01-01
  • 2013-01-31
  • 2016-08-30
  • 2015-09-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多