【问题标题】:inexplicable change in variable value变量值的莫名变化
【发布时间】:2013-01-23 08:56:40
【问题描述】:

我正面临变量值发生无法解释的变化。现在我对 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 个实例),但是在向监视窗口添加监视时; &amp;UPnPstarted 跟踪变量的内存位置,当我进入函数时我没有看到变化,所以在我看来它指的是相同的内存位置。

我只是不明白。对正在发生的事情有任何想法吗?

【问题讨论】:

    标签: c


    【解决方案1】:

    将变量标记为static 并不意味着会有一个实例在翻译单元之间共享(本质上是一个.c 源文件加上它引入的所有标题)。每个翻译直到都有自己的UPnPStarted 定义,因为每个.c 文件都包含定义UPnPStarted 的头文件。

    这意味着当函数UpnpSendAdvertisement()第一次被调用时,它正在访问它自己的UPnPStarted版本,该版本没有被修改过,其初始值不会改变0

    要在翻译单元之间共享同一个变量,请在声明时使用 extern 并提供一个定义:

    /* In the header file. */
    extern volatile int UPnPStarted;
    

    然后在一个,并且只有一个,.c 文件:

    volatile int UPnPStarted;
    

    【讨论】:

    • 没错,静态变量和你想的正好相反。来自 K&R:“static 声明应用于外部变量或函数,将该对象的范围限制为正在编译的源文件的其余部分。”
    • 哇,真快。你只花了 4 分钟就发布了 3:59 的答案,可能是在哪里输入答案。万分感谢!我将再次查找这些关键字的定义!但是代码现在可以工作了。
    • @Tieske,您可能会发现这是一个有用的问题:stackoverflow.com/questions/95890/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    • 2022-11-02
    相关资源
    最近更新 更多