错误:在C中的此函数中可以使用未初始化的X.

时间:2009-03-09 23:20:54

标签: c++ initialization

我收到此错误

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

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

如果我使Access静态工作,但我不喜欢让它静态,因为在每个其他调用中Access将被更新。有什么方法可以避免问题而不会让它变得静止?

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

4 个答案:

答案 0 :(得分: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:您将一些有用的操作与本地分配的对象的构造函数和析构函数相关联。

答案 1 :(得分: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说:

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

g ++非常满意。

这是我不知道的C和C ++之间的区别(但这不适合300个字符,因此我不能轻易地将其作为评论)。


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

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

答案 2 :(得分:1)

Access不是静态的,因此每次调用函数时都会创建一个新实例。只有在第一次通过时你才真正为它分配任何价值;函数退出后,该值将丢失。

如果您需要Access来保持对函数的调用,请将其设置为静态。

答案 3 :(得分:1)

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

考虑将代码简化为:

static MyStruct Access = Implementation(this_b);

这确保只在第一次运行方法时调用该函数,Access将保持调用之间的值。