archim
驱动牛犊
驱动牛犊
  • 注册日期2001-08-18
  • 最后登录2006-03-17
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
阅读:2736回复:15

如何防止.c里全局变量的重定义?

楼主#
更多 发布于:2002-10-15 09:53
有下面2个.c文件

1.c :
int aa; // 全局变量
...

2.c :
int aa; // 全局变量
...

当这2个文件在同一个工程当中时,用VC编译居然不会出现任何警告或者错误信息!!

如果想让编译器帮助我发现这些全局变量的重定义,VC提供了相关的编译选项没有??
archim
VanCheer
驱动老牛
驱动老牛
  • 注册日期2002-02-21
  • 最后登录2003-08-28
  • 粉丝0
  • 关注0
  • 积分-20分
  • 威望-10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-10-15 09:56
你那不是重定义,每个变量的“全局”是指在它所在文件可见,出了文件就等于没有定义了。
你可以试试在头文件里
extern int aa;
[img]http://www.driverdevelop.com/forum/upload/VanCheer/2003-03-21_mon.gif[/img][img]http://www.driverdevelop.com/forum/upload/VanCheer/2002-12-07_smallbaby.jpg[/img]
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-10-15 10:13
全局变量的作用域是文件 :D
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
archim
驱动牛犊
驱动牛犊
  • 注册日期2001-08-18
  • 最后登录2006-03-17
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-10-15 10:21
我再说的详细一些:

1.c
#include \"windows.h\"
#include \"stdio.h\"
#include \"conio.h\"

extern void JJ();

ULONG a;

int
main()
{

a = 100;

JJ();

printf(\"main::a=%d\\n\", a);

getch();

return 0;
}

2.c
#include \"windows.h\"
#include \"stdio.h\"
#include \"conio.h\"

ULONG a;

void
JJ()
{
a=10;
printf(\"JJ::a=%d\\n\", a);
}

运行的结果是2次打印输出都是10,这就是说在1.c和2.c里的aa变量其实都是指向相同的内存单元的。

这样,如果在完成一个较大的工程时,每个.c文件里也许都会定义一些全局变量。在整个工程中也许就会出现全局变量重名的情况。这些重名的变量之间也许根本就没有任何联系,但是VC在编译的时候却会让它们指向相同的地址,这就会带来很多问题!!
archim
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-10-15 11:26
我这会出现编译错误:

--------------------Configuration: 2 - Win32 Debug--------------------
Compiling...
1.cpp
Linking...
1.obj : error LNK2005: \"int  a\" (?a@@3HA) already defined in 2.obj

2.exe - 1 error(s), 0 warning(s)


 :D
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
archim
驱动牛犊
驱动牛犊
  • 注册日期2001-08-18
  • 最后登录2006-03-17
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-10-15 11:41
把文件的扩展名改成.cpp确实会出现这样的错误。
但是如果使用.c扩展名编译是没有问题的。

而写driver一般都是用.c作为文件扩展名的。
archim
wangshilin
游客
游客
6楼#
发布于:2002-10-15 16:13
确实有这个问题,如果是.C++就不会出现了,一定要用.C的话,如果是一个大工程,加强项目管理吧,编译器是不会发现问题的
archim
驱动牛犊
驱动牛犊
  • 注册日期2001-08-18
  • 最后登录2006-03-17
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-10-16 09:08
我用Borland的编译器编译的时候编译器就能发现这些变量重定义过了,并且给出警告信息。可见这是编译器的性能问题,而不是ANSI C的语法问题。

只可惜不能用bc来编译驱动程序。

!!
archim
VanCheer
驱动老牛
驱动老牛
  • 注册日期2002-02-21
  • 最后登录2003-08-28
  • 粉丝0
  • 关注0
  • 积分-20分
  • 威望-10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-10-16 09:17
我用Borland的编译器编译的时候编译器就能发现这些变量重定义过了,并且给出警告信息。可见这是编译器的性能问题,而不是ANSI C的语法问题。

只可惜不能用bc来编译驱动程序。

!!

BC比VC智商要高,很多时候它都能发出警告,比如死循环,没用的表达式,等等,VC比较弱一些,M$这方面弱一些。
[img]http://www.driverdevelop.com/forum/upload/VanCheer/2003-03-21_mon.gif[/img][img]http://www.driverdevelop.com/forum/upload/VanCheer/2002-12-07_smallbaby.jpg[/img]
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-10-16 10:32
看来以后编程要小心一些 :D
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
greenhand
驱动中牛
驱动中牛
  • 注册日期2002-04-07
  • 最后登录2005-10-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-10-16 16:50
在我的项目里我就是希望能在主程序和驱动程序里定义一个指向同一物理内存单元的指针,用来达到通信的目的,可是不能实现。更恐怖的是使得中断都不能正常进行,汗。


没想到老兄你无心插柳柳成阴了。
要向全世界宣告:“我是月光族的光荣一员,员、员、员……” [img]http://www.driverdevelop.com/forum/upload/greenhand/2003-01-08_007.jpg[/img]
bbear
驱动小牛
驱动小牛
  • 注册日期2002-08-20
  • 最后登录2009-04-16
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望3点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-10-17 09:34
我再说的详细一些:

1.c
#include \"windows.h\"
#include \"stdio.h\"
#include \"conio.h\"

extern void JJ();

ULONG a;

int
main()
{
a = 100;
return 0;
}

2.c
#include \"windows.h\"
#include \"stdio.h\"
#include \"conio.h\"

ULONG a;

void
JJ()
{
a=10;
}

运行的结果是2次打印输出都是10,这就是说在1.c和2.c里的aa变量其实都是指向相同的内存单元的。

这样,如果在完成一个较大的工程时,每个.c文件里也许都会定义一些全局变量。在整个工程中也许就会出现全局变量重名的情况。这些重名的变量之间也许根本就没有任何联系,但是VC在编译的时候却会让它们指向相同的地址,这就会带来很多问题!!


Archims
驱动牛犊
驱动牛犊
  • 注册日期2002-08-20
  • 最后登录2009-08-25
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-10-17 14:41
>在我的项目里我就是希望能在主程序和驱动程序里定义
>一个指向同一物理内存单元的指针,用来达到通信的目的,
>可是不实现。更恐怖的是使得中断都不能正常进行,汗

首先,很高兴有人的ID如我十分相近,你好
对于greenhand的想法,这是不合理大多数情况下也不可能的,简述如下:
1。准备使用的内存地址不可能位于系统内存区,你无法控制区程序的装载位置,也不能从内存池分配指定的位置的内存,应用程序无法访问系统内存区。
2。可以在用户内存区指定一个合理的虚拟内存地址并预留分配内存(当然,将来你的程序更改时要十分小心),但是驱动程序代码很难确定运行时所处哪个进程虚拟内存空间(参看DDK文档),所以驱动程序访问的指定位置的用户内存,可能是其他进程的数据,也可能是未分配或者换页到了磁盘的虚拟内存空间。
解决的方法,见DDK的缓冲区管理部分
greenhand
驱动中牛
驱动中牛
  • 注册日期2002-04-07
  • 最后登录2005-10-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-10-18 09:49
理论上来讲,1M以下的虚拟地址和物理地址是可以直接对应的,应该可以直接使用。杨强、李堂秋的那本书上就列了一个例子。
我也是这样才敢用的,结果搞的骑虎难下。
愁啊,为什么他们的行我的就不能用呢,不明白!!
要向全世界宣告:“我是月光族的光荣一员,员、员、员……” [img]http://www.driverdevelop.com/forum/upload/greenhand/2003-01-08_007.jpg[/img]
archim
驱动牛犊
驱动牛犊
  • 注册日期2001-08-18
  • 最后登录2006-03-17
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-10-18 09:56
这位大哥说的是在98下吧?

虚拟地址能不能访问是由OS来决定的,具体的说如果要访问的虚地址在OS的页表中存在,并且当前的线程有足够的权限,访问才能成功。

再顺便问一下“杨强、李堂秋”何许人也?
archim
greenhand
驱动中牛
驱动中牛
  • 注册日期2002-04-07
  • 最后登录2005-10-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2002-10-18 10:13
不错,是在98下面,总之我就是很晕了

那两人就是《win 9x虚拟设备驱动程序编程指南》的作者
我开始接触驱动看的第一本书
要向全世界宣告:“我是月光族的光荣一员,员、员、员……” [img]http://www.driverdevelop.com/forum/upload/greenhand/2003-01-08_007.jpg[/img]
游客

返回顶部