ANSI C兼容平台是否存在非零空指针?这类平台常见吗?
关于ANSI C中空指针与memset填充0字节的疑问
问题背景与核心疑问
已知ANSI C标准允许空指针的内存表示为非全0字节,据此提出以下两个问题:
- 是否存在符合ANSI C标准的实际平台,使得用
memset将结构体指针成员填充为全0字节后,该指针不等于NULL? - 这类平台的普及程度如何?能否举例说明?
注:本问题聚焦于ANSI C兼容环境中空指针的非零内存表示,与“NULL曾被定义为非0字面量”的问题无关。
验证代码
用于验证的代码(运行后若输出0,则说明填充0字节后的指针不等于NULL):
#include <string.h> #include <stdio.h> struct MyStruct { void *somePointer; }; int main() { struct MyStruct ms; memset(&ms, 0, sizeof(ms)); printf("%d\n", ms.somePointer == 0); }
原问题对应的代码:
struct MyStruct { void *somePointer; }; int main() { struct MyStruct ms; memset(&ms, 0, sizeof(ms)); /* 能否假设 ms.somePointer == NULL ? */ }
问题解答
1. 是否存在这类平台?
存在。ANSI C(C89及后续标准)仅规定NULL是表示空指针的常量,且空指针与NULL或整数0比较结果为真,并未强制要求空指针的内存表示必须是全0字节。因此完全存在符合标准的平台,其空指针的内存表示为非全0字节。
2. 普及程度与实例
这类平台非常罕见,仅存在于部分老旧的特殊架构系统中:
- DEC VAX/VMS:早期VMS系统里,32位环境下的空指针内存表示为
0xFFFFFFFF,而非全0字节。若用memset将指针填充为全0,此时该指针的值不等于系统的空指针,自然也不等于NULL。 - 早期IBM大型机(如OS/390旧版本):部分旧版IBM大型机的空指针采用非全0值表示,但现代版本已改为全0表示以提升兼容性。
当前主流平台(x86、x86_64、ARM、RISC-V等)均将空指针的内存表示定义为全0字节,因此在这些平台上,memset填充0后的指针会等于NULL。但从标准合规性角度,不能依赖这一行为,正确做法是直接将指针赋值为NULL,而非通过memset填充0字节。
内容的提问来源于stack exchange,提问作者math4tots
相关产品推荐
相关产品推荐

