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

时间:2011-04-10 02:21:41

标签: c++ c

static inline JGPlatformInfo* currentPlatform(){
    static JGPlatformInfo* platform = nil;

    if (platform == nil){
        JGPlatformInfo info = supportedPlatform();
        platform = &info;
    }

    return platform;    
}

我使用此代码获得了不一致的结果(C系列)platform的值无缘无故地更改,内存似乎是正确的。可能是什么导致了这个? inline关键字会影响这个吗?

5 个答案:

答案 0 :(得分:6)

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

现在有一些完全不同的东西 - 真正的问题:你正在返回一个自动变量的地址 - 即一个指向某个堆栈帧的指针 - 它已经坏了。

答案 1 :(得分:4)

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

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文件的第一次调用时返回。{/ p>

答案 2 :(得分:3)

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

您必须将变量设为extern并在一个翻译单元中定义。

答案 3 :(得分:3)

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

在您的源文件中:

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个字节的内存并返回指向它的指针。

答案 4 :(得分:-1)

原因内联功能将在您使用它的每个地方展开。 所以事实上你的代码中会有很多静态平台。 您应该删除“内联”,并且不要尝试返回临时变量的地址。