在CSAPP中看到的程序链接规则:
函数名, 有初值的全局变量, 编译器会把它作为"强"符号,
而无初值的全局变量, 编译器会把它作为"弱"符号.
链接的时候, 如果不同文件中出现同名的"强"符号, 链接失败.
如果同名的有一个"强"符号, 多个弱符号, 链接"强"符号, 丢弃"弱"符号.
如果只有多个同名的"弱"符号, 则随机选一个链入可执行文件, 这也是有道理的, 因为反正没有初值, 随便选一个就好了.
使用C程序用GCC验证这一过程, 没有问题, 但用C++程序, 以G++来编译, 出现了符号多次定义的链接错误.
//文件1:
int c;
int main (int argc, char const* argv[])
{
c+=1;
return 0;
}
//文件2:
int c;
//文件3:
int c:
问题出在编译上, gcc遇到int c;全局变量, 会把它作为Common符号,是一个"弱符号",
而g++在编译C++程序时, 遇到 int c全局变量, 会把它放在OBJ文件的BSS段里, 是"强"符号, 所以就出现了强符号冲突的情况.
gcc, g++在编译时, 对有非0初值的全局int, 会放在Data段, 而对0初值的全局int, 会放在BSS段, 放BSS里毕竟可以省可执行文件的体积. 这一点没区别.
但在处理没写初值的int时, 有了区别, 似乎g++会默认它初始化成0, 而gcc看它没初始化就让它Common了.