作者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/cn.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