c - 重新定义 NULL

标签 c null

我正在为地址 0x0000 有效且包含端口 I/O 的系统编写 C 代码。因此,任何访问 NULL 指针的可能错误都不会被发现,同时会导致危险行为。

出于这个原因,我希望将 NULL 重新定义为另一个地址,例如一个无效的地址。如果我不小心访问了这样的地址,我会得到一个硬件中断,我可以在其中处理错误。我碰巧有权访问此编译器的 stddef.h,因此我实际上可以更改标准 header 并重新定义 NULL。

我的问题是:这会与 C 标准冲突吗?据我从标准中的 7.17 可以看出,宏是实现定义的。标准中是否有任何其他地方声明 NULL 必须 为 0?

另一个问题是许多编译器通过将所有内容都设置为零来执行静态初始化,无论数据类型如何。尽管标准说编译器应该将整数设置为零并将指针设置为 NULL。如果我要为我的编译器重新定义 NULL,那么我知道这样的静态初始化将会失败。即使我大胆地手动更改了编译器 header ,我是否可以将其视为不正确的编译器行为?因为我确定这个特定的编译器在进行静态初始化时不会访问 NULL 宏。

最佳答案

C 标准不要求空指针位于机器地址零处。但是,将 0 常量转换为指针值必须导致 NULL 指针(§6.3.2.3/3),并且将空指针评估为 bool 值必须为 false .如果您真的确实想要一个零地址,而 NULL 不是零地址,这可能会有点尴尬。

尽管如此,通过对编译器和标准库进行(大量)修改,用替代位模式表示 NULL 并非不可能,同时仍然严格符合标准库。然而, 仅更改 NULL 本身的定义是不够的,因为 NULL 的计算结果为真。

具体来说,您需要:

  • 安排指针赋值(或强制转换为指针)中的文字零转换为一些其他魔法值,例如 -1
  • 安排指针和常量整数 0 之间的相等性测试来检查魔法值(§6.5.9/6)
  • 安排所有将指针类型评估为 bool 值的上下文,以检查是否与魔法值相等,而不是检查是否为零。这遵循相等性测试语义,但编译器可能会在内部以不同方式实现它。参见 §6.5.13/3、§6.5.14/3、§6.5.15/4、§6.5.3.3/5、§6.8.4.1/2、§6.8.5/4
  • 正如 caf 指出的那样,更新静态对象初始化的语义 (§6.7.8/10) 和部分复合初始化器 (§6.7.8/21) 以反射(reflect)新的空指针表示。
  • 创建一种替代方法来访问真正的地址零。

有些事情您不必处理。例如:

int x = 0;
void *p = (void*)x;

在此之后,p 不保证是空指针。只需要处理常量赋值(这是访问真实地址零的好方法)。同样:

int x = 0;
assert(x == (void*)0); // CAN BE FALSE

还有:

void *p = NULL;
int x = (int)p;

x 不保证为 0

简而言之,C 语言委员会显然考虑了这个条件,并且考虑了那些会为 NULL 选择替代表示的人。您现在所要做的就是对您的编译器进行重大更改,嘿,很快您就完成了:)

附带说明一下,可以在编译器正确之前通过源代码转换阶段来实现这些更改。也就是说,您需要添加预处理器 -> NULL 转换 -> 编译器 -> 汇编器 -> 链接器,而不是预处理器 -> 编译器 -> 汇编器 -> 链接器的正常流程。然后你可以做这样的转换:

p = 0;
if (p) { ... }
/* becomes */
p = (void*)-1;
if ((void*)(p) != (void*)(-1)) { ... }

这将需要一个完整的 C 解析器,以及一个类型解析器和 typedef 分析以及变量声明以确定哪些标识符对应于指针。但是,通过这样做,您可以避免必须更改编译器本身的代码生成部分。 clang可能对实现这一点很有用——我知道它在设计时就考虑到了这样的转换。当然,您仍然可能需要对标准库进行更改。

关于c - 重新定义 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5142251/

相关文章:

c - 写入/dev/input/mice 不能模拟鼠标点击

c++ - cpp中的assert.h有什么用?

java - com.sun.istack.internal.Nullable 注释和 Guice

arrays - plpgsql 函数以多维数组作为参数

c - 这是什么意思,我应该如何为大文件解决这个问题? (malloc_error_break)

c - 如何在 Linux 终端中优化 C 编译生成的可执行文件

C 指针算术

MySQL合并一些空值,而不是全部空值

Android通知空指针异常

python - Python中的空模式未充分利用?