2010-08-07 42 views
0

像PI這樣的語句對#define或者聲明它們是常量,因此編譯器可以進行優化,並且它變得不太容易出錯。然而,我想知道如何處理陳述中的字面數字?例如:字面數字被視爲常量嗎?

float x; 
const int y = 60; 
x = y/3.0f; 

在這個例子中,如何處理3.0f?它會繼承常量的優化嗎?

+6

你究竟是什麼意思? '3.0f' _is是一個常數。 – 2010-08-07 23:40:39

+0

我在這裏看到的真正問題是,如果編譯器會注意到,當它與x一起使用時,y在上下文中始終爲60,因此它會將該代碼優化爲'const int y = 60; float x = 20.0' – zebediah49 2010-08-07 23:43:42

+2

與幾乎所有標記爲'C++'__and__'C'的問題一樣,您需要決定您想要聽哪些語言。儘管語法相似,C和C++是完全不同的語言。 – sbi 2010-08-07 23:55:47

回答

10

什麼優化將發生取決於編譯器。就你而言,C和C++編譯器通常會有足夠的信息來優化你的源代碼到相同的機器代碼中。換句話說,它並不是真的很依賴文字常數在這段代碼中。

話雖如此,術語文字不斷的含義是在C和C++顯著不同(您標記在同一時間你的問題C和C++)。

  • 在C 603.0f和是常數,但y不是恆定。您可以撥打y一個常量限定變量如果你願意,但它是不是在C術語中不斷,在一定意義上,單一y不是常量表達式在C.

至於文字,在C語言中,術語文字僅適用於字符串文字(在C99中也是複合文字),即根本沒有代碼中的文字。

  • 在C++中,603.0.f文字,其形式常量表達式(積分和分別浮 - 點)。 y也是常數int類型,在某種意義上,單一的y常數表達式在C++中。

您可能會注意到這種差異的情況與優化無關,而與語言的定義方式無關。例如,使用上述y在文件範圍陣列類型聲明在C法律++,但不是在C

typedef int int_array[y]; /* OK in C++, ERROR in C */ 
+0

它在C99中是合法的,但是類型是可變長度數組,而不是普通數組。 – 2010-08-08 04:46:08

+0

@R:嗯,這取決於範圍。我暗示了一個文件範圍聲明(我編輯了明確指向文件範圍的答案)。 C99中的文件範圍中沒有VLA。 – AnT 2010-08-08 04:56:09

+0

至於術語*文字*,C99也在另一個上下文中使用這個術語,即* compound litteral *。很顯然,這裏的詞彙並不容易追蹤。 – 2010-08-08 06:24:45

1

由於使用#define你問預處理做文本替換,你的代碼是一樣的如下:

#define VAL 3.0f 

float x; 
const int y = 60; 
x = y/VAL; 

直接常量的值是如何優化顯然是依賴於編譯器。但是,如果您觀察彙編代碼(例如由gcc生成的代碼),您會注意到編譯器直接將編碼值爲3.0的二進制序列寫入浮點標準。

+1

請注意,宏在C++中被皺起了眉頭。 (它也有'C++'標記。) – sbi 2010-08-07 23:54:39

0

在某些體系結構,存在於可直接使用字符串文字的大小的限制。當字符串文字的大小過大時,編譯器需要將該常量存儲在只讀數據存儲器的某處,然後在需要時從內存中加載該值。

如果將值存儲在常量變量中,編譯器很有可能只存儲常量的一個值並正確使用。但是,如果#定義了常量,這只是讓預處理器將文字值放入代碼中,因此編譯器可能沒有意識到您正在使用相同的值並將常量存儲多次。正是由於這個原因,const變量比#defines更好。

0

答案取決於你是否使用C或C++,所以你需要選擇一個,並停止假裝他們是同一件事。在C中,const關鍵字未聲明常量;它聲明瞭一個變量,試圖修改該變量將調用未定義的行爲。在C中,除非它是靜態/全局的,並且打算將內部信息從一個模塊傳遞到另一個模塊,而不希望在其他模塊的編譯時進行修復,否則絕不應聲明const int y;(例如,共享庫中的const int my_library_version = 0x1001;可能有用,儘管函數調用返回值會更清晰)。

至於優化,沒有我知道的C編譯器會優化你的例子中的除法,並且甚至允許編譯器是否值得懷疑。對於C++,你應該請求C++專家來解釋(我不是其中的一個)。

相關問題