我面临着变量值无法解释的变化。现在,我对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/

10-12 14:41