1

我收到此错误

error: Access.Core may be used uninitialized in this function

这是我的代码:

 static int FirstTime = 1;
 MyStruct Access;

 if (FirstTime) {
   FirstTime = 0;
   Access = Implementation();
   DoSomething(Access);
 }

 if(Other_Variable) {
    Access = Implementation2();
    DoSomething(Access);
  }

  //The Other_Variable will be set to 1 and to 0 by other part of the code

我的代码就是这样,因为我只想第一次调用函数实现。在每次调用中,Access 变量都将被更新,因此将其设为静态没有多大意义。

如果我将 Access 设为静态,但我不喜欢将其设为静态,因为在其他所有调用中,Access 都会被更新。有什么方法可以避免问题而不使其成为静态?

此外,欢迎使用仅执行一次函数而不是使用静态变量的任何更好的选项。

4

4 回答 4

6

像这样(Access并删除FirstTimeif):

static MyStruct Access = Implementation(this_b);

您收到此警告的原因是静态变量在一次函数调用中仍然存在。它们的值在所有函数调用中保留(考虑哪个线程调用该函数)。所以,FirstTime将控制你是否初始化Access. 第一次调用代码所在的函数将正确初始化Access变量。但是对于每一个进一步的函数调用,FirstTime都为零,您将不再初始化Access,因此将在代码中使用未初始化的变量。

编辑:现在,根据您的更新信息,您说您有两个Implementation功能。第一次您想使用一个功能,而其他所有时间您都想使用另一个功能。那么这个怎么样:

 // static will be false/zero by default
 static bool AlreadyCalled;
 MyStruct Access;

 if (!AlreadyCalled) {
   Access = Implementation();
   AlreadyCalled = true;
 } else {
   Access = Implementation2();
 }

不过,根据您的实际用例,可能有更好的方法来处理这个问题。例如,为什么不更新 的状态Access,像这样:

// let the default constructor initialize it
// to a plausible state
static MyStruct Access;

// use RAII to update the state of Access when this
// function returns. 
MyUpdater updater(Access);

// now, do whatever the function does. 

像这样的东西MyUpdater

struct MyUpdater {
    MyStruct &s;
    MyUpdater(MyStruct &s):s(s) { }
    ~MyUpdater() {
        s.ChangeState();
    }
};

该模式称为RAII:您将一些有用的操作与本地分配对象的构造函数和析构函数相关联。

于 2009-03-09T23:28:45.583 回答
2

@litb 的回答很有趣。下面是一个等效的程序。代码按照 C++ 中的说明编译和工作,但不能在 C 中编译。

#include <stdio.h>

static int newval(void) { return 3; }

void inc(void)
{
    static int a = newval();

    a++;
    printf("%d\n", a);
}

int main(void)
{
    int i;
    for (i = 0; i < 10; i++)
        inc();
    return(0);
}

gcc 说:

xc:在函数'inc'中:xc:7:错误:初始化元素不是常量

g++ 对此非常满意。

这是我不知道的 C 和 C++ 之间的区别(但这不适合 300 个字符,所以我不能轻易地发表评论)。


@Eduardo 在评论中提出了一个问题:“为什么 C 不允许这样做而 C++ 允许这样做?”。 由于答案是300多个字符...

正如@litb 在评论中所说,在 C 中,您只能将常量用于静态变量的初始化程序。这部分是因为值是在调用 main() 之前设置的,并且在调用 main() 之前没有调用用户定义的函数。相比之下,C++ 允许在调用 main() 之前由(用户定义的)构造函数初始化全局变量和静态变量,因此没有理由不允许其他用户定义的函数也被调用,因此初始化是合理的。使用 C89,您可以使用自动(局部)变量的初始化程序受到限制;在 C99 中,您几乎可以使用任何表达式来初始化任何局部变量。

于 2009-03-09T23:45:20.457 回答
1

访问不是静态的,因此每次调用函数时都会创建一个新实例。只有在第一次通过时,您才真正为它分配任何值;一旦函数退出,这个值就会丢失。

如果您需要 Access 在对函数的调用中保持不变,请将其设为静态。

于 2009-03-09T23:27:40.920 回答
1

Access不是静态的,因此必须在每次调用中创建。

考虑将代码简化为:

static MyStruct Access = Implementation(this_b);

这确保了该函数只会在该方法第一次运行时被调用,并且Access在调用之间保存该值。

于 2009-03-09T23:30:20.307 回答