c - 当接收到 null-but-not-0 和 0-but-not-null 指针时,如何测试代码的行为?

标签 c testing null compiler-optimization zero

我想要修改一段代码,使其能够在空指针的物理表示不为 0 的系统上运行。到目前为止,我完全忽略了 null 和 0 之间的区别 - 直到今天,我在实践中还没有研究任何具有这种区别的系统 - 但仍然如此。

所以,我再次阅读了有关空值的 C 常见问题解答,特别是 5.19 ,了解如何获取“实际零”指针。好吧,我想在我正在编写的单元测试中执行此操作,但是 - 我担心其中一些“技巧”实际上会被合理的编译器优化掉。

例如,使用 memset() 和 `memcmp():GCC 和 Clang see right through that ,这样:

#include <stdio.h>
#include <string.h>

int foo(void* p)
{
    void* ref;
    memset(&ref, 0, sizeof(ref));
    return (memcmp(&p, &ref, sizeof(p)) == 0 ) ? 123: 456000;
}

int bar(void* p)
{
    memset(&p,  0, sizeof(p));
    return (p == 0) ? 123: 456000;
}

变成,说:

foo:                                    # @foo
        test    rdi, rdi
        mov     ecx, 123
        mov     eax, 456000
        cmove   eax, ecx
        ret
bar:                                    # @bar
        mov     eax, 123
        ret

那么,除了不进行优化的编译之外,如何可靠地“强制清零”指针?

注意:感谢 @Lundin 指出,如果我使用 memset(),我可能也想使用 memcmp())。

最佳答案

memset 是正确的解决方案。而且由于您使用使用零作为空指针实现的编译器进行编译,因此可能很难阻止优化的发生。

不过你有一个错误。

  • 对指针的检查(如 if(p))会检查该指针是否为空指针。
  • 比较 p == 0p == (void*)0p == NULL 检查该指针是否为空指针。

因此,p == 0不会检查内部表示是否为零。你必须使用类似的东西:

void* ref;
memset(&ref, 0, sizeof ref);

if(memcmp(&p, &ref, sizeof p)==0)

对于使用零作为空指针表示的系统来说,这可能不会带来任何革命性的结果。

关于c - 当接收到 null-but-not-0 和 0-but-not-null 指针时,如何测试代码的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68206997/

相关文章:

c++ - 如何使用 Telnet 库从服务器发送查询并从客户端接收回显

无注入(inject)测试

JSON 字段设置为 null vs 字段不存在

php - MySQL NOT NULL 不适用于 PHP

c - gdb 检查和打印给出不同的值

c - 监视(Windows)C 中特定进程的 CPU 和内存消耗?

testing - 使用 jmeter 对 300 个并发用户进行负载测试

scala - 测试 Right[Seq[MyClass]] 和属性

windows - 如何使用 Windows 批处理脚本将空 ASCII 字符 (nul) 写入文件?

C程序不能在UNIX上运行但可以在Dev-C++上运行?