2010-05-15 54 views
1

對於這個代碼:我的機器上這是否與endian-ness有關?

#include<stdio.h> 

void hello() { printf("hello\n"); } 
void bye() { printf("bye\n"); } 

int main() { 
    printf("%p\n", hello); 
    printf("%p\n", bye); 
    return 0; 
} 

輸出:

0x80483f4 
0x8048408 

[第二地址是在值更大]上Codepad

0x8048541 
0x8048511 

[第二地址是價值較小]

這與機器的排序有什麼關係?如果沒有,

  • 爲什麼地址排序的區別?

  • 另外,爲什麼差異的差異?

    0x8048541 - 0x8048511 =的0x30

    0x8048408 - 0x80483f4 = 0x14的


順便說一句,我只是檢查。此代碼(從here拍攝)說,這兩種機器是Little-Endian

#include<stdio.h> 
int main() {  
    int num = 1; 
    if(*(char *)&num == 1) 
     printf("Little-Endian\n"); 
    else  
     printf("Big-Endian\n"); 
    return 0;  
} 
+0

字節順序與多字節數據類型中的字節順序有關。與地址無關。 (例如,這與地址的存儲方式有關。) – GManNickG 2010-05-15 06:05:22

+0

@GMan - 拯救獨角獸:是的,我是這麼認爲的。 – Lazer 2010-05-15 06:43:10

回答

5

它與endinanness無關,但與C++標準無關。 C++不需要按照你看到它們到磁盤的順序編寫函數(並且考慮跨文件鏈接,甚至連接其他庫,這是不可行的),它可以按照它希望的順序編寫它們。

關於實際值之間的差異,一個編譯器可能會在塊周圍添加防護以防止內存覆蓋(或其他相關的東西,通常僅在調試模式下)。沒有什麼能夠阻止編譯器在你的兩個函數之間編寫其他函數。請記住,即使一個簡單的hello world應用程序帶有數千字節的可執行代碼。

底線是:從不假設事物在記憶中的位置。你的假設幾乎總是錯的。爲什麼甚至假設?無論如何,編寫正常的,安全的,結構化的代碼沒有任何好處。

+0

感謝您的答案!你所說的回答我的問題。但只是想知道,會有*某種方式*告訴編譯器如何在內存中放置對象。 **在編譯器的內存管理部分有一些文本,我可以更好地理解這一點嗎?** – Lazer 2010-05-16 04:48:06

+0

嗯,不是真的,你只能真正告訴編譯器半高級別的意思(即C代碼)。編譯器處理將其翻譯成代碼段。這就是說,具體的編譯器有不同的方式讓你表達結構如何被打包(字段之間的空間)和對齊(距離4/8/16/32/64位邊界的距離)。你不能告訴編譯器關於正在編譯的實際代碼的任何信息。 – Blindy 2010-05-16 07:38:05

3

的位置和功能的順序是非常特定於平臺,架構,編譯器,編譯器版本,甚至編譯器標誌(尤其是)。

6

不,這與endianness無關。它與編譯器和鏈接器有關,它們可以自由地在內存中對函數定義進行排序,因爲它們看起來合適,而且不同的編譯器選擇不同的內存佈局策略。

1

您正在打印功能地址。這純粹是在鏈接器的領域,編譯器不會做任何涉及到創建程序的二進制圖像。除了爲每個功能生成機器碼的斑點之外。鏈接器將這些斑點排列在最終圖像中。一些連接器具有影響順序的命令行選項,否則它很不重要。

Endian-ness在這裏不會影響printf()的輸出。它知道如何在同一臺機器上生成指針值的情況下正確解釋字節。