我在用C编写垃圾收集器时遇到了麻烦。我给你一个最小的,可验证的例子。
第一个文件负责处理虚拟机
exact
然后我有实际的垃圾收集器,最小化的代码是:
startswith
最后,最小的主要是:
#include <stdlib.h>
#include <stdint.h>
typedef int32_t value_t;
typedef enum {
Lb, Lb1, Lb2, Lb3, Lb4, Lb5,
Ib, Ob
} reg_bank_t;
static value_t* memory_start;
static value_t* R[8];
value_t* engine_get_Lb(void) { return R[Lb]; }
value_t engine_run() {
memory_start = memory_get_start();
for (reg_bank_t pseudo_bank = Lb; pseudo_bank <= Lb5; ++pseudo_bank)
R[pseudo_bank] = memory_start + (pseudo_bank - Lb) * 32;
value_t* block = memory_allocate();
}
我用gdb得到的问题是,如果我打印#include <stdlib.h>
#include <stdint.h>
typedef int32_t value_t;
static value_t* memory_start = NULL;
void memory_setup(size_t total_byte_size) {
memory_start = calloc(total_byte_size, 1);
}
void* memory_get_start() { return memory_start; }
void mark(value_t* base){
value_t vbase = 0;
}
value_t* memory_allocate() {
mark(engine_get_Lb());
return engine_get_Lb();
}
我得到地址(value_t *)0x7ffff490a800而在函数int main(int argc, char* argv[]) {
memory_setup(1000000);
engine_run();
return 0;
}
内打印engine_get_Lb()
时我得到了地址(value_t *)0xfffffffff490a800。
知道为什么会这样吗?
可能有用的补充文件
makefile
base
包含说明的文件.asm
mark
答案 0 :(得分:1)
recursive
使用前未声明 value_t* memory_allocate() {
mark(engine_get_Lb());
return engine_get_Lb();
}
。根据C语言的过时且危险的规则,编译器假定返回engine_get_Lb
。它已在C标准中弃用了相当长的一段时间,现在终于被删除了。
创建一个包含所有全局函数声明的头文件,并在所有源文件中int
。
您的编译器应至少在默认设置下警告您此错误。如果确实如此,您应该在继续之前阅读并完全理解警告。如果没有,请考虑升级。如果无法升级,请将#include
永久添加到编译标志中。另请考虑-Wall -Wextra -Werror
和-Wpedantic
。