使用静态const而不是#define有什么含义?

时间:2009-09-25 11:45:09

标签: c

gcc抱怨这个:

#include <stdio.h>
static const int YY = 1024;
extern int main(int argc, char*argv[])
{  
  static char x[YY];
}

$ gcc -c test1.c test1.c:在函数main': test1.c:5: error: storage size of中,x'不是常数 test1.c:5:错误:变量“x”的大小太大

从x的定义中删除“static”,一切都很好。

我不清楚这里发生了什么:肯定YY 不变?

我一直认为“静态const”方法比“#define”更可取。在这种情况下有没有办法使用“静态const”?

5 个答案:

答案 0 :(得分:14)

在C中,const变量不是“真正的”编译时常量......它实际上只是一个你不允许修改的普通变量。因此,您不能使用const int变量来指定数组的大小。

现在,gcc有一个扩展,允许您在运行时指定数组的大小如果在堆栈上创建数组。这就是为什么当您从static的定义中省略x时,代码会编译。但是,这在标准C中仍然不合法。

解决方案:使用#define

编辑:请注意,这是C和C ++不同的一点。在C ++中,const int 一个真正的编译时常量,可用于指定数组的大小等。

答案 1 :(得分:12)

您可以使用'enum'或'define'来声明大小:

#define          XX   1024 
static int const YY = 1024;
           enum{ ZZ = 1024 };

extern int main(void){

  static char x[XX]; // no error
  *(int*)&XX = 123;  // error: lvalue required as unary ‘&’ operand


  static char y[YY]; // error: storage size of ‘y’ isn’t constant
  *(int*)&YY = 123;  // no error, the value of a const may change


  static char z[ZZ]; // no error
  *(int*)&ZZ = 123;  // error: lvalue required as unary ‘&’ operand
}

答案 2 :(得分:1)

因为您将x声明为'static',使其成为全局变量。它只是在声明它的main()函数中才知道。通过在任何函数之外声明YY,您已将其设为全局。 'static'也使它成为一个全局的,但只有这个文件才知道。

如果您将YY声明为'const int YY = 1024',则编译器可能会将其视为#define,但具有类型。这取决于编译器。

此时有两件事可能出错。

1:

在调用main()之前,所有全局变量都在运行时初始化。

由于x和YY都是全局变量,因此它们都被初始化。

因此,全局x的运行时初始化必须根据YY中的值分配空间。如果编译器没有像使用类型的#define那样处理YY,则必须对运行时值进行编译时判断。它可能假设int的最大可能值,这实际上太大了。 (或者因为你签了它而可能是否定的。)

如果您只将YY更改为短,最好是无符号短,那么可能会感兴趣。然后它的最大值是64K。

2:

您的系统可能会限制全局空间的大小。您没有指定目标平台和操作系统,但有些只有这么多。

由于您将x声明为YY,因此您已将其设置为从全局空间中获取YY字符。其中的每个字母都基本上是全球性的。如果系统上的全局空间有限,那么它的1024个字符可能太多了。

如果将x声明为char的指针,那么它将需要sizeof(char *)个字节。 (4个字节是大多数系统上指针的大小。)有了这个,你需要将指针设置为正确的malloc空间的地址。

通过声明没有'static'的x,它变成一个局部变量,只有在执行拥有函数后才会初始化。它的空间取自堆栈,而不是全球空间。 (这对于堆栈非常有限的系统或线程来说仍然是一个问题。)YY的值早已被这一点设置,所以没有问题。

此外:

我不记得是否有任何保证全局变量以任何顺序初始化。如果没有,则可以在YY之前初始化x。如果发生这种情况,那么YY将只包含RAM的随机内容。

答案 3 :(得分:0)

接下来马丁B的回答,你可以这样做:

#include <stdio.h>

#define XSIZE 1024

static const int YY = XSIZE;

int main(int argc, char*argv[])
{  
    static char x[XSIZE];
}

答案 4 :(得分:0)

/* SHOULDN'T THIS WORK IN C++? */
// .h

class C {
public:
   static const int kSIZE;
   int a[kSIZE]; // error: array bound is not an integer constant
};


// .cc

const int C::kSIZE = 1;


/*  WORKS FINE */    
// .h

class C {
public:
   enum eCONST { kSIZE = 1 };
   int a[kSIZE];
};