有效指针的可能值是什么?

时间:2019-01-23 15:00:54

标签: c

标准是否限制了可能的内存地址(我将其解释为指针的可能值)?您的代码能否依靠一些永远不会使用的值仍然可以完全移植?

我刚刚在我们的代码库(这是一个C库)中看到了这一点,我想知道它是否总是可以。我不确定这是什么意思,但显然不只是检查可能的null。

int LOG(const char* func, const char* file,
                 int lineno, severity level, const char* msg)
{
    const unsigned long u_func = (unsigned long)func;
    const unsigned long u_file = (unsigned long)file;
    const unsigned long u_msg   = (unsigned long)msg;

    if(u_func < 0x400 || u_file < 0x400 || u_msg  < 0x400 ||
       (unsigned)lineno > 10000 || (unsigned)level > LOG_DEBUG)
    {
        fprintf(stderr, "log function called with bad args");
        return -1;
    }
    //...
}

另一种可能的用例是将布尔标志存储在指针内,而不是在单独的成员变量中作为优化。我认为C ++ 11小字符串优化可以做到这一点,但是我可能是错的。

编辑:

如果您定义了实现,如您所提到的,您可以在编译时检测到它吗?

2 个答案:

答案 0 :(得分:2)

  

标准是否限制了可能的内存地址(我将其解释为指针的可能值)?

C ++(据我所知也不是C)标准并不限制可能的内存地址。

  

您的代码可以依靠一些永远不会使用的值还是仍然完全可移植吗?

一个程序无条件地依赖于已定义(或未由标准指定)细节的实现,将无法完全移植到所有具体和理论上的标准实现中。

但是,使用平台检测宏,可以通过仅在细节可靠的系统上有条件地依赖细节来使程序可移植。


P.S。技术上您不能依靠的另一件事:unsigned long不能保证能够表示所有指针值(uintptr_t是)。

答案 1 :(得分:1)

标准术语是“安全派生指针”。如果不能在程序中使用不能安全派生的指针(例如,数字常量),则由实现定义。

您可以使用std::pointer_safetyhttps://en.cppreference.com/w/cpp/memory/gc/pointer_safety

检查指针安全模型。