标准是否限制了可能的内存地址(我将其解释为指针的可能值)?您的代码能否依靠一些永远不会使用的值仍然可以完全移植?
我刚刚在我们的代码库(这是一个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小字符串优化可以做到这一点,但是我可能是错的。
编辑:
如果您定义了实现,如您所提到的,您可以在编译时检测到它吗?
答案 0 :(得分:2)
标准是否限制了可能的内存地址(我将其解释为指针的可能值)?
C ++(据我所知也不是C)标准并不限制可能的内存地址。
您的代码可以依靠一些永远不会使用的值还是仍然完全可移植吗?
一个程序无条件地依赖于已定义(或未由标准指定)细节的实现,将无法完全移植到所有具体和理论上的标准实现中。
但是,使用平台检测宏,可以通过仅在细节可靠的系统上有条件地依赖细节来使程序可移植。
P.S。技术上您不能依靠的另一件事:unsigned long
不能保证能够表示所有指针值(uintptr_t
是)。
答案 1 :(得分:1)
标准术语是“安全派生指针”。如果不能在程序中使用不能安全派生的指针(例如,数字常量),则由实现定义。
您可以使用std::pointer_safety
:https://en.cppreference.com/w/cpp/memory/gc/pointer_safety