大佬教程收集整理的这篇文章主要介绍了c – 外部可选?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
// file1.c int first; void f(void) { first = 2; }
// file2.c #include <stdio.h> int first; void f(); int main(void) { first = 1; f(); printf("%d",first); }
这两个文件,由于某些原因将编译并链接在一起,并打印出来2.我始终觉得,除非我将一个或另一个(但不是两个)的定义标记为extern,否则不会编译,其实是外在的一切!
gcc file1.c file2.c
会发生什么是编译器会看到你有两个名为同一个东西的全局变量,也没有被初始化.然后,它将将未初始化的全局变量放在代码**的“常用”部分中.换句话说,它将只有一个“第一个”变量的副本.这是因为gcc的默认值为-fcommon
如果要使用-fno-common标志进行编译,则会收到您正在考虑的错误:
/tmp/ccZNeN8c.o:(.bss+0x0): multiple deFinition of `first' /tmp/cc09s2r7.o:(.bss+0x0): first defined here collect2: ld returned 1 exit status
要解决这个问题,你可以将extern添加到除变量之外的所有变量中.
警告:
现在假设你有两个不同大小的全局未初始化的数组:
// file1.c int first[10]; // file2.c int first[20];
好的猜测,用gcc -Wall file1.c file2.c编译它们不会产生任何警告或者错误,即使它的大小不同,这个变量是很常见的!
//objdump from file1.c: 0000000000000028 O *COM* 0000000000000020 first //objdump from file2.c: 0000000000000050 O *COM* 0000000000000020 first
这是全球变量的危险之一.
**如果您查看* .o文件的objdump(您必须使用gcc -c编译才能生成它们),您将首先看到放在通用(* COM *)部分中:
@H_193_2@mike@mike-VirtualBox:~/C$objdump -t file2.o a.o: file format elf64-x86-64 SymBOL TABLE: 0000000000000000 l df *ABS* 0000000000000000 file2.c 0000000000000000 l d .text 0000000000000000 .text 0000000000000000 l d .data 0000000000000000 .data 0000000000000000 l d .bss 0000000000000000 .bss 0000000000000000 l d .rodata 0000000000000000 .rodata 0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack 0000000000000000 l d .eh_frame 0000000000000000 .eh_frame 0000000000000000 l d .comment 0000000000000000 .comment 0000000000000004 O *COM* 0000000000000004 first 0000000000000000 g F .text 0000000000000039 main 0000000000000000 *UND* 0000000000000000 f 0000000000000000 *UND* 0000000000000000 printf以上是大佬教程为你收集整理的c – 外部可选?全部内容,希望文章能够帮你解决c – 外部可选?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。