【发布时间】:2011-07-05 18:18:08
【问题描述】:
我正在为地址 0x0000 有效且包含端口 I/O 的系统编写 C 代码。因此,任何可能访问 NULL 指针的错误都不会被检测到,同时会导致危险行为。
出于这个原因,我希望将 NULL 重新定义为另一个地址,例如一个无效的地址。如果我不小心访问了这样的地址,我会得到一个可以处理错误的硬件中断。我碰巧可以访问这个编译器的 stddef.h,所以我实际上可以更改标准头文件并重新定义 NULL。
我的问题是:这会与 C 标准冲突吗?据我从标准中的 7.17 可以看出,宏是实现定义的。标准中是否有其他地方声明 NULL 必须为 0?
另一个问题是大量编译器通过将所有内容设置为零来执行静态初始化,无论数据类型如何。尽管标准说编译器应该将整数设置为零并将指针设置为 NULL。如果我为我的编译器重新定义 NULL,那么我知道这样的静态初始化将会失败。即使我大胆地手动更改了编译器头文件,我是否可以将其视为不正确的编译器行为?因为我确定这个特定的编译器在进行静态初始化时不会访问 NULL 宏。
【问题讨论】:
-
这是一个非常好的问题。我没有给你的答案,但我不得不问:你确定不能像在“正常”系统中那样将你的有效东西移到 0x00 并让 NULL 成为一个无效地址吗?如果您不能,那么唯一可以安全使用的无效地址将是您可以确定您可以分配然后
mprotect确保安全的地址。或者,如果平台没有 ASLR 等,地址超出平台物理内存。祝你好运。 -
如果您的代码使用
if(ptr) { /* do something on ptr*/ },它将如何工作?如果 NULL 定义与 0x0 不同,它会起作用吗? -
C 指针与内存地址没有强制关系。只要遵守指针运算规则,指针值可以是任何值。大多数实现选择使用内存地址作为指针值,但它们可以使用任何东西,只要它是同构的。
-
@bdonlan 这也会违反 MISRA-C 中的(咨询)规则。
-
@Andreas 是的,这也是我的想法。硬件人员不应该被允许设计软件应该运行的硬件! :)