这是我拥有的一个最小代码示例(我try 运行这个最小示例以确保它重现我看到的问题):
void testfn(void) {
printf("Hello, world!\n");
}
int main(int argc, char *argv[]) {
printf("fp: %p\n", &testfn);
return 0;
}
我得到的输出是fp: 0x0000000000000000
,表明我试图打印的函数指针是0.我try 在testfn()
上使用CC __attribute__((noinline))
属性,得到了相同的结果.
我正在为RISC-V系统进行编译并在QEMU中运行.我认为也许printf()
实现有缺陷(尽管它对我来说看起来很好,而且其他指针打印也很好),所以我try 将函数指针转换为无符号的64位int,然后循环那么多次迭代(我认识到这在技术上是JB,但通常在实践中有效,这是一个愚蠢的测试),但循环恰好执行0次迭代:
void __attribute__((noinline)) testfn(void) {
printf("Hello, world!\n");
}
int main(int argc, char *argv[]) {
void (*fn)(void) = &testfn;
printf("Testing printf...\n");
printf("fp addr: %p\n", &fn);
fn();
for (int i = 0; i < (unsigned long long) fn; ++i) {
printf("Here!\n");
}
printf("fp: %p\n", fn);
return 0;
}
这将产生以下输出:
Testing printf...
fp addr: 0x0000000000003FA8
Hello, world!
fp: 0x0000000000000000
以下是用于编译的命令:riscv64-unknown-elf-gcc -Wall -O0 -fno-omit-frame-pointer -ggdb -gdwarf-2 -MD -mcmodel=medany -ffreestanding -fno-common -nostdlib -mno-relax -I. -fno-stack-protector -fno-pie -no-pie -c -o user/rkttest.o user/rkttest.c
这是我用来运行QEMU的命令; qemu-system-riscv64 -machine virt -bios none -kernel kernel/kernel -m 128M -smp 3 -nographic -global virtio-mmio.force-legacy=false -drive file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
.
在我看来,函数指针总是零,除非我试图将其称为函数.在我看来,这就像是一个编译器错误或我的环境中发生的一些奇怪的事情,但我想我应该把它放在Stack OverFlow上.我是不是错过了什么?