2015-08-03 36 views
0

我正在通过一些openGL教程,因为它们都具有C++语法,所以我需要将它们转换为C语法,并且我有一些全局变量的问题。初始化全局变量使用整数字面值,但不使用const类型变量

所以,我有我的extern声明在共享头LUtil.h

#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; 
... 

而且我在该声明发生

#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文件有用。但是,如果我在LUtil.c

int gColorMode = COLOR_MODE_CYAN; 

初始化这样的gColorMode常量我得到一个编译错误,说我的初始化程序不可尽管已经宣布COLOR_MODE_CYAN一个const与它初始化不变。

这是为什么?

回答

4

C,一个变量声明const不是不断,这就是所谓的const -qualified变量。它不被视为编译时常量表达式。

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

FWIW,与const一个变量是在C++情况下的实常数(积分常量表达式)。

+0

不要使用幻数是代码(好吧,有例外)。仅供参考:“字面常量”(我更喜欢这个)是一个非标准术语。该标准使用[_(integer)constant_](http://port70.net/~nsz/c/c11/n1570.html#6.4.4)。这仅仅表明C没有真正的常量(而C++实际上只有一种嵌合体)。 – Olaf

+0

@Olaf谢谢你,先生,正如6.4.4中提到的,现在更新我的答案。 :-) –

+0

实际上不需要更新,对我来说已经很好了。 (我只是想添加一些背景 - 不能这样做:-) – Olaf

1

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

即使它被标记const,你可以回非const和修改(请不要!),因为这(可能还有其他原因),它要求阅读发光存取存储器您的const int常数的值,则初始化另一个变量时这是不允许的(它必须是一个编译时间常数。)

相反,在头文件使用#define

+1

我同意头文件中的那些'const'值应该是#defines。然后编译器问题永远不会出现,并且值不会变化,并且不会占用内存空间我会将#define直接放在头文件中,然后唯一的extern语句是gProjectionScale和gColorMode – user3629249

0

const int的COLOR_MODE_CYAN

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

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