我面临着变量值无法解释的变化。现在,我对C的使用还不是很丰富,我用一只手在键盘上编写的大多数代码,另一只手在K&R中跟踪页面,所以请保持柔和。
我有一个C项目,在Visual Studio 2010中,是pupnp库的Lua绑定。这是一些相关的代码;
文件:luaUPnPdefinitions.h(摘录)
#ifndef LuaUPnPdefinitions_h
#define LuaUPnPdefinitions_h
...
// tracker for library being started or not
volatile static int UPnPStarted;
...
#endif /* LuaUPnPdefinitions_h */
档案:LuaUPnP.h(完整档案)
#ifndef LuaUPnP_h
#define LuaUPnP_h
#include "upnp.h"
#include "upnptools.h"
#include "uuid.h"
#include <lua.h>
#include <lauxlib.h>
#include "luaIXML.h"
#include "darksidesync_aux.h"
#include "luaUPnPdefinitions.h"
#include "luaUPnPsupport.h"
#include "luaUPnPcallback.h"
#endif /* LuaUPnP_h */
文件:LuaUPnP.c(节选)
#include "luaUPnP.h" // only include in this file
...
static int L_UpnpSendAdvertisement(lua_State *L)
{
int result = UpnpSendAdvertisement(checkdevice(L, 1), luaL_checkint(L,2));
if (result != UPNP_E_SUCCESS) return pushUPnPerror(L, result, NULL);
lua_pushinteger(L, 1);
return 1;
}
...
文件:LuaUPnPsupport.h(节选)
#ifndef LuaUPnPsupport_h
#define LuaUPnPsupport_h
//#include <ixml.h>
#include <lua.h>
#include <lauxlib.h>
#include "luaIXML.h"
#include "upnptools.h"
#include "luaUPnPdefinitions.h"
...
UpnpDevice_Handle checkdevice(lua_State *L, int idx);
...
#endif /* LuaUPnPsupport_h */
文件:LuaUPnPsupport.c(节选)
#include "luaUPnPsupport.h" // only include in this file
...
UpnpDevice_Handle checkdevice(lua_State *L, int idx)
{
pLuaDevice dev;
luaL_checkudata(L, idx, LPNP_DEVICE_MT);
if (! UPnPStarted) luaL_error(L, UpnpGetErrorMessage(UPNP_E_FINISH));
dev = (pLuaDevice)lua_touserdata(L, idx);
return dev->device;
}
现在解决问题;
UPnPstarted
静态变量基本上跟踪pupnp库后台进程是否已启动。现在,当在某个点(可重现)在
L_UpnpSendAdvertisement
函数进行调试时,然后是UPnPstarted == 1
,但是在我碰到这一行时;int result = UpnpSendAdvertisement(checkdevice(L, 1), luaL_checkint(L,2));
然后进入调试器,跳转到
checkdevice
函数(在LuaUPnPsupport.c文件中),并且UPnPstarted
的值立即更改为UPnPstarted == 0
。我迷路了。它是一个静态变量,因此应该共享,为什么仅通过进入其他函数就可以更改值?
在调试器的监视窗口中,值以红色点亮,表明它们已更改。最初,我认为文件的顺序错误,并且
UPnPstarted
变量是重复的(或具有2个实例),但是在将监视添加到监视窗口时; &UPnPstarted
跟踪变量的内存位置,当我进入该函数时看不到任何变化,因此在我看来,它指向相同的内存位置。我就是不明白。有什么想法吗?
最佳答案
将变量标记为static
并不意味着在翻译单元之间共享一个实例(实际上是一个.c
源文件加上它引入的所有标头)。直到每个翻译都有自己的UPnPStarted
定义,因为每个.c
文件都包括定义了UPnPStarted
的头文件。
这意味着,当第一次调用函数UpnpSendAdvertisement()
时,它正在访问自己的版本的UPnPStarted
,该版本尚未修改,并且其初始值不变,为0
。
要在翻译单元之间共享相同的变量,请在声明时使用extern
并提供准确的一个定义:
/* In the header file. */
extern volatile int UPnPStarted;
然后在一个且只有一个
.c
文件中:volatile int UPnPStarted;
关于c - 变量值发生莫名其妙的变化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14475703/