当前位置: 技术问答>linux和unix
使用make时发现的一个值得小心的问题(新鲜出炉)!!!
来源: 互联网 发布时间:2015-09-13
本文导语: 这个问题是我刚刚在工作中碰到的。 比如下列小程序: 代码: /******************************************/ #include static char *head; void change(char *); /******************************************/ int main(void) { char n...
这个问题是我刚刚在工作中碰到的。
比如下列小程序:
代码:
/******************************************/
#include
static char *head;
void change(char *);
/******************************************/
int
main(void)
{
char name[] = "XiongBin Xiong.n";
char *p;
p = name;
head = p;
printf("main()_1:%s",head);
change(p);
printf("main()_2:%s",head);
exit(0);
}
/********************************************/
void
change(char *ptr)
{
char *q;
q = ptr;
q = q + 5;
head = q;
printf("change():%s",head);
}
/*******************************************/
就一个文件,直接gcc编译,运行,输出结果为:
main()_1:XiongBin Xiong.
change():Bin Xiong.
main()_2:Bin Xiong.
当按照文中标示分为3个文件ourh.h,main.c,change.c使用make进行编译,运行,输出结果为:
main()_1:XiongBin Xiong.
change():Bin Xiong.
main()_2:XiongBin Xiong.
两者输出结果是不一样的。
我现在的认为是,程序段分开编译时,对于一个函数中全局变量的改变不能引起其他函数中该变量的值的变化。但到底里头是怎么一回事,到底有什么规则呢?我还不知道/。
有待学习。请各位高手指点。
比如下列小程序:
代码:
/******************************************/
#include
static char *head;
void change(char *);
/******************************************/
int
main(void)
{
char name[] = "XiongBin Xiong.n";
char *p;
p = name;
head = p;
printf("main()_1:%s",head);
change(p);
printf("main()_2:%s",head);
exit(0);
}
/********************************************/
void
change(char *ptr)
{
char *q;
q = ptr;
q = q + 5;
head = q;
printf("change():%s",head);
}
/*******************************************/
就一个文件,直接gcc编译,运行,输出结果为:
main()_1:XiongBin Xiong.
change():Bin Xiong.
main()_2:Bin Xiong.
当按照文中标示分为3个文件ourh.h,main.c,change.c使用make进行编译,运行,输出结果为:
main()_1:XiongBin Xiong.
change():Bin Xiong.
main()_2:XiongBin Xiong.
两者输出结果是不一样的。
我现在的认为是,程序段分开编译时,对于一个函数中全局变量的改变不能引起其他函数中该变量的值的变化。但到底里头是怎么一回事,到底有什么规则呢?我还不知道/。
有待学习。请各位高手指点。
|
这个问题应该是编译的问题,你肯定是编译成2个.O。然后链接的。
你的static char *head; 是在头文件中的,所以编译的时候是有2个全局的head量,分别在2个.O里面。因为本.O已经找到了这个变量的申明所以不会在编译的时候报重复申明。
你可以试一下吧头文件的去掉,然后再main.c头上加上static char *head;在change.c头上加上 extern static char *head;就应该对了
你的static char *head; 是在头文件中的,所以编译的时候是有2个全局的head量,分别在2个.O里面。因为本.O已经找到了这个变量的申明所以不会在编译的时候报重复申明。
你可以试一下吧头文件的去掉,然后再main.c头上加上static char *head;在change.c头上加上 extern static char *head;就应该对了
|
楼主对static的全局变量不够了解
static char *head。在一个c文件里出现一次,就分一个空间。在头文件里被包含
用nm查看可知
# nm a.out
080495f0 A __bss_start
080482d0 t call_gmon_start
080483d0 T change
080495f0 b completed.1
080495c4 d __CTOR_END__
080495c0 d __CTOR_LIST__
080494ec D __data_start
080494ec W data_start
08048468 t __do_global_ctors_aux
080482f4 t __do_global_dtors_aux
080494f0 D __dso_handle
080495cc d __DTOR_END__
080495c8 d __DTOR_LIST__
080494f8 D _DYNAMIC
080495f0 A _edata
080484e8 r __EH_FRAME_BEGIN__
080495fc A _end
U exit@@GLIBC_2.0
0804848c T _fini
080494ec A __fini_array_end
080494ec A __fini_array_start
080484a8 R _fp_hw
08048330 t frame_dummy
080484e8 r __FRAME_END__
080495d4 D _GLOBAL_OFFSET_TABLE_
w __gmon_start__
-----------------------
080495f4 b head
---------------------
080495f8 b head
----------------------
08048254 T _init
080494ec A __init_array_end
080494ec A __init_array_start
080484ac R _IO_stdin_used
080495d0 d __JCR_END__
080495d0 d __JCR_LIST__
w _Jv_RegisterClasses
08048434 T __libc_csu_fini
08048404 T __libc_csu_init
U __libc_start_main@@GLIBC_2.0
0804835c T main
080494f4 d p.0
U printf@@GLIBC_2.0
080482ac T _start
static char *head。在一个c文件里出现一次,就分一个空间。在头文件里被包含
用nm查看可知
# nm a.out
080495f0 A __bss_start
080482d0 t call_gmon_start
080483d0 T change
080495f0 b completed.1
080495c4 d __CTOR_END__
080495c0 d __CTOR_LIST__
080494ec D __data_start
080494ec W data_start
08048468 t __do_global_ctors_aux
080482f4 t __do_global_dtors_aux
080494f0 D __dso_handle
080495cc d __DTOR_END__
080495c8 d __DTOR_LIST__
080494f8 D _DYNAMIC
080495f0 A _edata
080484e8 r __EH_FRAME_BEGIN__
080495fc A _end
U exit@@GLIBC_2.0
0804848c T _fini
080494ec A __fini_array_end
080494ec A __fini_array_start
080484a8 R _fp_hw
08048330 t frame_dummy
080484e8 r __FRAME_END__
080495d4 D _GLOBAL_OFFSET_TABLE_
w __gmon_start__
-----------------------
080495f4 b head
---------------------
080495f8 b head
----------------------
08048254 T _init
080494ec A __init_array_end
080494ec A __init_array_start
080484ac R _IO_stdin_used
080495d0 d __JCR_END__
080495d0 d __JCR_LIST__
w _Jv_RegisterClasses
08048434 T __libc_csu_fini
08048404 T __libc_csu_init
U __libc_start_main@@GLIBC_2.0
0804835c T main
080494f4 d p.0
U printf@@GLIBC_2.0
080482ac T _start
|
昨晚的回复没了:(¥#%#
在模块内部有效
在模块内部有效
|
和make根本就没有关系
实际上就是一个head变量和两个head变量的问题
实际上就是一个head变量和两个head变量的问题
|
不过.h中是用extern char *head;main中是用char *head;
不能加static,加了编译不过,
gcc -c main.c
In file included from main.c:1:
test.h:3: multiple storage classes in declaration of `head'
*** Error code 1
不知道为什么?
================================================================
我想是因为你既然已经定义了 static char *head; 那么 head 这个符号就不可以被其它模块引用,你如果又在头文件中声明 extern char* head,就成为一个矛盾。
不能加static,加了编译不过,
gcc -c main.c
In file included from main.c:1:
test.h:3: multiple storage classes in declaration of `head'
*** Error code 1
不知道为什么?
================================================================
我想是因为你既然已经定义了 static char *head; 那么 head 这个符号就不可以被其它模块引用,你如果又在头文件中声明 extern char* head,就成为一个矛盾。
|
it's none of the business of make, it's your programming error.
|
静态变量好像是局部有效的吧,好像是不可以在其它文件中调用