我的搜索foo今天似乎缺乏。
我想知道根据std C ++是否 legal 来通过(unsigned(?))char *检查“任何”内存位置。通过任何位置,我指的是程序内对象或数组(或数组内)的任何有效地址。
举例来说:
void passAnyObjectOrArrayOrSomethingElseValid(void* pObj) {
unsigned char* pMemory = static_cast<unsigned char*>(pObj)
MyTypeIdentifyier x = tryToFigureOutWhatThisIs(pMemory);
}
免责声明:这个问题纯属学术问题。我不打算把它放到生产代码中!通过 legal 我的意思是,如果它真的是 legal 根据标准,那就是它可以在所有实现的100%上工作。 (不仅仅是在x86或一些常见的硬件上。)
子问题:static_cast
是从void *地址到char *指针的正确工具吗?
答案 0 :(得分:6)
C ++假定严格别名,这意味着两个根本不同类型的指针不会为同一个值设置别名。
但是,正如bdonlan正确指出的那样,该标准对char
和unsigned char
指针进行了例外处理。
因此,通常这是任何指针类型读取任何故意地址(可能是任何类型)的未定义行为,但对于unsigned char
的特定情况,如问题中所示允许(ISO 14882:2003 3.10(15))。
static_cast
执行编译时类型检查,因此不太可能始终有效。在这种情况下,您需要reinterpret_cast
。
答案 1 :(得分:2)
根据ISO / IEC 9899:1999(E)§6.5/ 7:
7.对象的存储值只能由具有其中一个的左值表达式访问 以下类型:
- 与对象的有效类型兼容的类型
- [...]
- 字符类型
因此通过unsigned char
取消引用并检查(有效)指针是合法的(在C中)。但是,你在那里找到的内容是未指定的; tryToFigureOutWhatThisIs
没有明确的方法来实际弄清楚它在看什么。我这里没有C ++规范的副本,但我怀疑它使用相同的定义,以保持兼容性。
答案 2 :(得分:0)
您只能使用char*
,而不是unsigned char*
。使用unsigned char*
将破坏严格的别名规则并调用未定义的行为,但char*
存在异常。然而,试图用你读的内存做任何事情是非常可疑的,很可能做一些未定义的事情。这就是为什么它很少用于惯用的C ++代码。