【问题标题】:Initializing global variable works with integer literal but not with const type variable [duplicate]初始化全局变量适用于整数文字,但不适用于 const 类型变量 [重复]
【发布时间】:2015-08-03 12:03:05
【问题描述】:

我正在学习一些 openGL 教程,因为它们都有 C++ 语法,我需要将它们转换为 C 语法,而且我在使用全局变量时遇到了一些问题。

所以我在共享头文件 LUtil.h 中有我的 extern 声明

#ifndef LUTIL_H
#define LUTIL_H

#include "LOpenGL.h"
#include <stdio.h>
#include <stdbool.h>

//Color modes
extern const int COLOR_MODE_CYAN;
extern const int COLOR_MODE_MULTI;

//Screen constants
extern const int SCREEN_WIDTH;
extern const int SCREEN_HEIGHT;
extern const int SCREEN_FPS;

extern int gColorMode;
extern GLfloat gProjectionScale;
...

我有我的 LUtil.c 文件,声明发生在其中

#include "LUtil.h"

//The current color rendering mode
const int COLOR_MODE_CYAN = 0;
const int COLOR_MODE_MULTI = 1;

//constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_FPS = 60;

//The projection scale
int gColorMode = 0;
GLfloat gProjectionScale = 1.f;
...

现在,如果我这样编译它就可以了。但是如果我在 LUtil.c 中像这样初始化 gColorMode 常量

int gColorMode = COLOR_MODE_CYAN;

我收到一个编译器错误,说我的初始化程序不是常量,尽管我已经声明了 COLOR_MODE_CYANconst 并使用它进行了初始化。

这是为什么?

【问题讨论】:

    标签: c initialization constants


    【解决方案1】:

    C 中,声明为const 的变量不是常量,它被称为const 限定变量。它不被视为编译时常量表达式。

    您需要使用 整数常量#define 来完成您的工作。

    FWIW,const 的变量在C++ 的情况下是实常数(整型常数表达式)。

    【讨论】:

    • 不要使用幻数是代码(嗯,也有例外)。仅供参考:“字面常量”(我也更喜欢这个)是一个非标准术语。该标准使用(integer) constant。仅此一点就表明 C 没有真正的常量(而 C++ 实际上只有一种嵌合体)。
    • @Olaf 谢谢先生,正如 6.4.4 中所述,现在更新我的答案。 :-)
    • 其实不需要更新,我已经很好了。 (我只是想添加一些背景 - 忍不住这样做:-)
    • 好的,谢谢。这里的天气变热了:-( 希望你也没事。我不认为这是一个错误,因为 literal 是一个常用术语,C 委员会应该一直使用它,请参阅string literal。有点奇怪,他们确实在此处添加了 enum 常量(这不是语法元素,而是标识符)。嗯。为了保持一致性……
    • @Olaf 今天我来晚了,因为一些紧急的工作过量了,刚刚完成。这里是季风,所以真的很酷。关于“lireral”,到目前为止,标准中只提到了string literal,正如您所说的那样。所有其他都是 -constant :-)
    【解决方案2】:

    const 在 C 中实际上并没有创建一个“常量”。您仍然会得到一个变量(保留内存),但编译器只是禁止写入该变量。

    即使它被标记为const,你可以将它转换回非常量并修改它(请不要!)因为这个(可能还有其他原因),它需要发出内存读取以访问 const int 常量的值,这在初始化另一个变量时是不允许的(它必须是编译时常量。)

    改为在头文件中使用#define

    【讨论】:

    • 我同意头文件中的那些'const'值应该是#defines。那么编译器问题就永远不会浮出水面,并且值不会改变,也不会占用内存空间我会将#defines直接放在标题中,那么唯一的extern语句将是gProjectionScale和gColorMode
    【解决方案3】:

    const int COLOR_MODE_CYAN

    即使它是常量,它仍然是一个变量(这只是意味着如果您尝试使用代码对其进行修改,编译器将抛出编译时错误)。这意味着它将有一个内存位置和一个值,当程序将被加载到内存中时。它的值可以通过 = 运算符计算。并且所有的运算符都应该放在函数定义中,因为它们只能在运行时解析。

    并且由于您要为其分配值的变量是全局变量。它的初始值必须在编译时声明,以便编译器可以将其放入适当的段(.bss 或 .data)。但是分配的值是一个变量,为了找出它的 value = 运算符,必​​须执行。这不能在编译时完成。所以编译器会抛出一个错误,给我一个常量值,我可以分配给这个全局变量,比如 3、4、5。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-11
      • 1970-01-01
      • 2020-05-04
      相关资源
      最近更新 更多