从内联函数返回静态变量的值

Return value of static variable from inline function

本文关键字:变量 静态 返回 函数      更新时间:2023-10-16
static inline JGPlatformInfo* currentPlatform(){
    static JGPlatformInfo* platform = nil;
    if (platform == nil){
        JGPlatformInfo info = supportedPlatform();
        platform = &info;
    }
    return platform;    
}

我得到与此代码(C族)不一致的结果。platform的值无缘无故地改变,内存似乎是正确的。是什么原因造成的呢?inline关键字会影响这一点吗?

我猜你在头文件中有,对吧?然后,每个翻译单元都有自己的platform变量副本。

现在对于一些完全不同的东西- 真正的问题:你返回一个自动变量的地址-即指向某个堆栈帧的指针-这是坏的

我不确定是什么导致了这个问题,但是通常的(更简单、更安全、更习惯的)方法是:

inline JGPlatformInfo &currentPlatform() {
    // supportedPlatform() will only be called once
    static JGPlatformInfo platform = supportedPlatform();
    return platform; // & platform would work if you must return a pointer
}

我怀疑您当前问题的原因是将函数限定为static导致编译器为每个翻译单元创建该变量的单独实例。它不是在每个函数调用时返回NULL,而是在每个.cpp文件的第一次调用时返回。

您定义的变量总是临时的。这意味着当您离开作用域时,变量将被销毁,并且指向它的指针将无效(或者更糟:它将指向它不应该指向的有效位置)。这就是需要动态分配的地方。下面是我如何达到你想要的效果:

在源文件中:

JGPlatformInfo* gCurrentPlatform = NULL;

如果你真的想内联这个函数,把它放在你的头文件中:

extern JGPlatformInfo* gCurrentPlatform;
...
// I'm not too familiar with C, but it seems like adding static
// to an inline function would be redundant
inline JGPlatformInfo* currentPlatform()
{
    if (!gCurrentPlatform)
    {
        gCurrentPlatform = malloc(sizeof(JGPlatformInfo));
        *gCurrentPlatform = supportedPlatform();
    }
    return gCurrentPlatform;
}

malloc(x)分配x字节的内存并返回指向它的指针。

对于C99版本的内联函数,inline函数不允许声明具有静态存储持续时间的变量——这样做会调用未定义的行为。

您必须使变量为extern,并在一个翻译单元中定义它。

因为内联函数将在您使用它的每个地方展开。实际上在你的代码中会有很多静态平台。你应该删除"inline",不要试图返回临时变量的地址。