全局变量似乎有两个不同的地址......?
Global Variable Seems To Have Two Different Addresses...?
考虑以下 4 个文件:
[core.h]
#pragma once
static int MY_MARK = -1;
[count.h]
#pragma once
#include "core.h"
#include <stdarg.h>
#define Count(...) CountImpl(&MY_MARK, __VA_ARGS__, &MY_MARK)
int CountImpl(void*, ...);
[count.c]
#include "count.h"
int CountImpl(void* dummy, ...) {
int count = 0;
va_list lst;
va_start(lst, dummy);
for(;;) {
void* ptr = va_arg(lst, void *);
if(ptr == &MY_MARK) {break;}
++count;
}
va_end(lst);
return count;
}
[WeirdProblem.c]
#include <tchar.h>
#include "count.h"
int _tmain(int argc, wchar_t* argv[], wchar_t* envp[]) {
int a = 1;
int b = 2;
int c = 3;
int d = Count(&a, &b, &c);
return 0;
}
我正在使用 Microsoft Visual Studio Community 2013。
当 运行 上面的代码时,我希望 'd' 变量的值为 3。问题是执行永远不会从循环中中断,因为它不比较 'ptr' 和'&MY_MARK' 相等。 (最终它会在尝试读取受保护的内存或其他内容时抛出错误。)
实际上,我在 Watch window 中看到了两个不同的地址:
(int*)ptr 0x000000013f8d9004 {WeirdProblemTest.exe!int MY_MARK} {-1} int *
&MY_MARK 0x000000013f8d9000 {WeirdProblemTest.exe!int MY_MARK} {-1} int *
我知道我可以使用 'dummy' 变量而不是引用“&MY_MARK”来解决这个问题,但这不是重点。
我真的需要了解发生了什么,因为同样的问题发生在我的代码的不同部分,而且那里没有很好的解决方法。
抱歉这么长 post,但我没办法让它更短。
您已将 .h
文件中的变量声明和定义为 static
,这意味着 每个 文件 #includes
header 将获得自己的 private 变量副本。
您需要将 core.h
拆分为 core.h
和 core.c
,如下所示:
core.h:
#pragma once
extern int MY_MARK;
core.c:
#include "core.h"
int MY_MARK = -1;
所有其他文件应该 #include "core.h"
,编译和 linking 时你应该 link in core.c
考虑以下 4 个文件:
[core.h]
#pragma once
static int MY_MARK = -1;
[count.h]
#pragma once
#include "core.h"
#include <stdarg.h>
#define Count(...) CountImpl(&MY_MARK, __VA_ARGS__, &MY_MARK)
int CountImpl(void*, ...);
[count.c]
#include "count.h"
int CountImpl(void* dummy, ...) {
int count = 0;
va_list lst;
va_start(lst, dummy);
for(;;) {
void* ptr = va_arg(lst, void *);
if(ptr == &MY_MARK) {break;}
++count;
}
va_end(lst);
return count;
}
[WeirdProblem.c]
#include <tchar.h>
#include "count.h"
int _tmain(int argc, wchar_t* argv[], wchar_t* envp[]) {
int a = 1;
int b = 2;
int c = 3;
int d = Count(&a, &b, &c);
return 0;
}
我正在使用 Microsoft Visual Studio Community 2013。
当 运行 上面的代码时,我希望 'd' 变量的值为 3。问题是执行永远不会从循环中中断,因为它不比较 'ptr' 和'&MY_MARK' 相等。 (最终它会在尝试读取受保护的内存或其他内容时抛出错误。)
实际上,我在 Watch window 中看到了两个不同的地址:
(int*)ptr 0x000000013f8d9004 {WeirdProblemTest.exe!int MY_MARK} {-1} int *
&MY_MARK 0x000000013f8d9000 {WeirdProblemTest.exe!int MY_MARK} {-1} int *
我知道我可以使用 'dummy' 变量而不是引用“&MY_MARK”来解决这个问题,但这不是重点。
我真的需要了解发生了什么,因为同样的问题发生在我的代码的不同部分,而且那里没有很好的解决方法。
抱歉这么长 post,但我没办法让它更短。
您已将 .h
文件中的变量声明和定义为 static
,这意味着 每个 文件 #includes
header 将获得自己的 private 变量副本。
您需要将 core.h
拆分为 core.h
和 core.c
,如下所示:
core.h:
#pragma once
extern int MY_MARK;
core.c:
#include "core.h"
int MY_MARK = -1;
所有其他文件应该 #include "core.h"
,编译和 linking 时你应该 link in core.c