作者Tverous (Orah~)
看板C_and_CPP
標題[問題] 外部變數static問題
時間Fri Aug 4 09:18:53 2017
開發平台(Platform): (Ex: Win10, Linux, ...)
Linux
編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
GCC
問題(Question):
最近在c primer plus中看到一段有關使用全域變數的一種方法
/* constant.h -- defines some global constants */
static const double PI = 3.14159;
static const char * MONTHS[12] =
{"January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"};
/* file1.c -- use global constants defined elsewhere */
#include "constant.h"
/* file2.c -- use global constants defined elsewhere */
#include "constant.h"
書上說不使用static關鍵字,那麼包含在file1.c和file2.c檔案中的constant.h將會導
致每個使用相同識別符號所定義宣告的檔案,都不被ANSI標準所支援
想知道是那邊違反標準?因為就算沒有使用static編譯執行似乎也沒有錯誤?
在這麻煩各位 感謝
程式碼(Code):(請善用置底文網頁, 記得排版)
http://ideone.com/jLsWKu
補充說明(Supplement):
原文圖片:
http://imgur.com/a/npcsk
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 111.82.152.86
※ 文章網址: https://webptt.com/m.aspx?n=bbs/C_and_CPP/M.1501809537.A.F43.html
※ 編輯: Tverous (111.82.152.86), 08/04/2017 09:20:50
1F:→ james732: 你沒有加static又給多個.c檔include應該就會link error 08/04 09:32
2F:推 Hazukashiine: compile 的下一步是 link, 如果沒有用 static 指定 08/04 09:35
3F:→ Hazukashiine: 是 internal linkage, 可能會造成識別符名稱的汙染 08/04 09:35
4F:→ Tverous: 想請問汙染具體來說是怎樣?因為假如使用個區域變數不是 08/04 10:45
5F:→ Tverous: 就直接隱藏掉全域變數嘛? 08/04 10:46
6F:推 stucode: 沒有用static修飾的file-scope變數是external linkage 08/04 11:35
7F:→ stucode: 這表示它可以被任何編譯單元參考到 08/04 11:36
8F:→ stucode: 以你的例子而言 file1跟file2會各有一個變數定義 08/04 11:36
9F:→ stucode: 假設沒有用static修飾 當程式中使用到該變數時 08/04 11:36
10F:→ stucode: linker會不知道要將其鏈結到哪個變數定義 08/04 11:36
11F:→ stucode: 相對來說 若是加了static 在file1中的變數定義 08/04 11:36
12F:→ stucode: 就只會在file1中使用時被看見 file2同理 08/04 11:37
13F:→ stucode: 至於你會沒有遇到錯誤 可能是你個別編譯兩個檔案 08/04 11:37
14F:→ stucode: 並且沒有鏈結它們 又或是像書中所寫 08/04 11:37
15F:→ stucode: 鏈結器幫你做了不合標準的額外處理 08/04 11:37
16F:→ Tverous: 大概了解了 感謝各位前輩 08/04 12:15
17F:→ PkmX: 題外話其實C標準J.5.11 Multiple External Definition有特別 08/05 01:18
18F:→ PkmX: 提到很多實作都會支援可以多個定義 只要不打架就好 08/05 01:18
19F:→ PkmX: 例如全域變數如果沒有初始化gcc會預設把他們都丟到common 08/05 01:20
20F:→ PkmX: section內 而linker會把所有object file的common symbol合併 08/05 01:20
21F:→ PkmX: 所以就算有多個定義只要大小一樣也是ok的 08/05 01:22
22F:→ PkmX: 這個功能可以在編譯的時候下gcc -fno-common關掉 08/05 01:23