2014-11-08 60 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