static在標頭檔中定義變數的問題

來源:互聯網
上載者:User

看到有一位同學在標頭檔中這麼寫:

?
12 static
const wchar_t* g_str1 = …
static
const wchar_t* g_str2 = …

這種定義變數的方式我從來沒有見過,而且它還能順利通過編譯,於是我很想知道編譯器是如何處理這種變數定義的。

 

定義全域變數時使用static,意味著該變數的範圍只限於定義它的源檔案中,其它源檔案不能訪問。既然這種定義方式出現在標頭檔中,那麼可以很自然地推測:包含了該標頭檔的所有源檔案中都定義了這些變數,即該標頭檔被包含了多少次,這些變數就定義了多少次。

 

假如將上面兩行代碼的static去掉,編譯的時候就會出現變數重定義的錯誤,這進一步證實了上面的推測,因為沒有static的話變數的範圍是全域的,定義了兩個以上的同名變數就會出現該錯誤。

 

推測終究是推測,要真正證實這個推測還要通過寫代碼來驗證。驗證的方式是:在標頭檔中使用static定義變數,在多個源檔案中包含該標頭檔,然後在每個源檔案中輸出變數的地址,同時在一個源檔案中改變變數的值並輸出,在另一個源檔案中也輸出。如果每個源檔案的輸出都不同,則推測得證;否則推測是錯誤的。

 

下面是定義變數的標頭檔的代碼:

?
1234 //Header.h #pragma once
  static
int g_int = 3;

 

接下來在另一個標頭檔中聲明兩個測試函數:

?
12345 //Functions.h #pragma once
  void
TestSource1();
void
TestSource2();

 

分別在兩個源檔案中定義這兩個測試函數:

?
12345678910 //Source1.cpp #include <stdio.h>
#include "Header.h"
  void
TestSource1() {
      wprintf(L"g_int's address in Source1.cpp: %08x\n", &g_int);
    g_int = 5;
    wprintf(L"g_int's value in Source1.cpp: %d\n", g_int);
}
?
123456789 //Source2.cpp #include <stdio.h>
#include "Header.h"
  void
TestSource2() {
      wprintf(L"g_int's address in Source2.cpp: %08x\n", &g_int);
    wprintf(L"g_int's value in Source2.cpp: %d\n", g_int);
}

 

最後在main函數中調用這兩個測試函數:

?
12345678 //Main.cpp #include "Functions.h"
  int
wmain() {
      TestSource1();
    TestSource2();
}

 

運行該程式:

 

可以看到,雖然在代碼中好像使用了相同的變數,但是實際上使用的是不同的變數,在每個源檔案中都有單獨的變數。所以,在標頭檔中定義static變數會造成變數多次定義,造成記憶體空間的浪費,而且也不是真正的全域變數。應該避免使用這種定義方式。

 

作為對比,下面使用正確的方式來定義全域變數:

?
1234 //Header.h #pragma once
  extern
int g_int;
?
123456789101112 //Source1.cpp #include <stdio.h>
#include "Header.h"
  int
g_int = 3;
  void
TestSource1() {
      wprintf(L"g_int's address in Source1.cpp: %08x\n", &g_int);
    g_int = 5;
    wprintf(L"g_int's value in Source1.cpp: %d\n", g_int);
}

 

其它檔案不變。

 

運行程式:

可以看到,這次兩個源檔案中使用的都是同一個變數。要注意的是,使用extern聲明變數時不能帶有初始值,否則仍然屬於變數定義,會出現變數重定義的錯誤。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.