2014-11-08 61 views
1

欢迎来到90年代,如何在1990年的const定义中添加2个整数?

我使用的是旧的Mac OS 7.01 API,我需要定义一个带有四个常量数组的“Rect”结构。可悲的是,我总是得到“Rect”定义的“需要不变”的错误。不过,我们正在谈论一个24岁的编译器。

Rect shapeRect = {100, 100, 200, 200}; // Works 

const int shapeSize = 10; 
int shapeX = 0; // Cannot be const 
int shapeY = 0; // Cannot be const 

Rect shapeRect = {shapeX - shapeSize, shapeY - shapeSize, shapeX + shapeSize, shapeY + shapeSize }; // Error: "requires constant" 

我试着定义多个常量与所有4个值计算,但我仍然在同一行上得到相同的错误。

const shapeRectT = shapeX - shapeSize; 
... 

Rect shapeRect - {shapeRectT, ...}; 

我的猜测是shapeRectT常量不是常量?我是C语言的初学者,但我相信这个问题可能很容易修复,但这是一个旧的编译器,而且事情可能会有所不同,我不知道新的C标准是否改变了这个东西。

编辑:我发现这方面的文档API(QuickDraw的):https://developer.apple.com/legacy/library/documentation/mac/pdf/ImagingWithQuickDraw.pdf

回答

2

的问题是关系到我们现在都已经忘记了C89的局限性。

那时您不可能在全局变量的初始化程序中使用非litterals。只有当地的struct变量允许非注射表达。

这个限制是由于代码执行真的开始于main()(实际上是一个存根初始化stdin,stdout和环境然后调用main)的事实。没有为全局初始化生成的代码。只有在作为可执行文件映像的一部分加载的值。

我只是可以用我的旧微软编译器确认这一行为。这是MS-DOS,但是从1990年2月,这么漂亮靠近你使用一个:

struct R {int a, b; }; /* simple structure for the demo */ 

struct R a = { 1,2 }; /* global variable with litteral init: ok ! */ 
const int v1 =10;  
const int v2 =20; 
struct R z = { v1,v2 }; /* Error message, "illegal initialization" */ 

int main() 
{ 
struct R w = { v1,v2}; /* here it is accepted, because corresponding 
          initialisation code could be generated/executed 
          as part of the function */ 
return 0; 
} 
+2

即使在C11中,struct R z的初始化仍然无效。 – mafso 2014-11-09 01:54:30

1
  1. 做手工。 (不推荐)
  2. 使用一些常量来初始化(不是const限定变量)。

    enum {shapeX_Init = 0, shapeY_Init = 0, shapeSize_Init = 10}; 
    const int shapeSize = shapeSize_Init; 
    int shapeX = shapeX_Init; // Cannot be const 
    int shapeY = shapeY_Init; // Cannot be const 
    
    Rect shapeRect = {shapeX_Init - shapeSize_Init, shapeY_Init - shapeSize_Init, 
            shapeX_Init + shapeSize_Init, shapeY_Init + shapeSize_Init }; 
    
+0

我试过,但我仍然不能得到我想要做的工作:因为shapeX被改变了/我试图让shapeX_Init = shapeX,时间。可悲的是,我不能改变常数:/ 我认为我使用的API必须有一种方法来转换矩形结构,但我没有找到任何文档:/ – fordcars 2014-11-08 23:31:15

+0

您可以使用编译时常量初始化一个对象(可能是'const'-qualified)或创建其他常量,但从来没有相反的方式。 – Deduplicator 2014-11-08 23:43:43

2

是的,有在C89和C99之间的聚合(和工会)初始化的差异。从C99 rationale(PDF第95页)引述:

的C89委员会审议了关于允许自动的聚合初始化到由一个大括号内的系列任意执行时间表达的,而不只是那些可用于翻译静态初始化器C89委员会并没有确定一套可以避免病态案例的规则,而且也没有过于武断,因此C89委员会选择只允许静态初始化器。这是重新考虑的,执行时表达式在C99中是有效的。

一些C89编译器将此作为扩展实现。你的不是。您可以修复这样的错误:

Rect shapeRect; 
shapeRect.top = shapeX - shapeSize; 
shapeRect.left = shapeY - shapeSize; 
shapeRect.bottom = shapeX + shapeSize; 
shapeRect.right = shapeY + shapeSize; 
+0

谢谢!我找到了API(QuickDraw)的文档,我会使用你的建议。 – fordcars 2014-11-08 23:44:33