哪些虚拟指针值是可以的
Which dummy pointer values are okay
这是我想了很久的事情。我经常看到人们使用 1 或 -1 作为指针的虚拟值。为了安全需要不同的变量。
这样使用指针可以吗?我想 -1 没问题。但是使用其他负数也可以吗?我可以确定 1 不是已用内存位置吗?如果是这样,我最多可以使用哪个值的内存指针。
P.s。我知道在指针中存储其他数据,尤其是正值,是非常非常糟糕的做法。但我只是想知道在任何现实生活情况下会产生什么后果。
我敢打赌你的编译器会在你这样做时发出警告?这本身应该告诉你这是不好的,应该避免。
许多老旧的代码都有针对值的 NULL(或 nullptr)的保护措施。你把 -1 放在那里,它变成一个无符号的 0xffffffff 地址(32 位域)到那个指针,它会愉快地 运行 尽管你不希望它 运行 的各种事情通过。最好的情况是立即访问冲突/段错误。最坏的情况是没有人注意到,2 个月后事情变得一团糟,你被发现是,好吧...... 'not smart person' 谁非法将非指针值放入指针并炸毁了东西。像这样的错误可能会丢掉工作。
顺便说一句,为什么 'people' 想在指针中使用 1 或 -1?在其中删除 nullptr、NULL 或您的语言支持的任何内容并完成它。否则在那里放一个有效的指针并称之为好。
这取决于您的编译器和(主要)OS——在大多数操作系统上,存在永远无效的地址范围。因此,在这样的 OS 上,可以安全地将诸如 'magic' 值的地址用于永远不会与任何有效对象进行比较的指针。只要您从不取消引用它们,它们就应该没问题——即使您取消引用它,OS 也可以定义行为(通常会抛出特定信号)。
一种更便携的替代方法是创建 'dummy' 全局对象并将指向它们的指针用作您的特殊标记。没有其他有效的对象指针会与虚拟对象指针进行比较,并且虚拟对象的额外开销是最小的。
您可以便携使用的唯一指针值是指向当前存在的对象的指针和空指针。 (我忽略了函数指针和成员指针。)
空指针的目的是拥有一个不指向任何对象的指针值,并且与任何指向对象的指针相比都不相等。该语言只为每种指针类型提供一个这样的指针值。
有时拥有多个不同的指针值会很方便。
您可以自己定义这些值 -- 例如:
const some_type* foo = reinterpret_cast<some_type*>(-1);
const some_type* bar = reinterpret_cast<some_type*>(-2);
严格来说,使用任何一个值,即使不取消引用它,都有未定义的行为。 (我知道 C 就是这种情况;我认为 C++ 也是如此。)但如果您碰巧知道这些值与指向实际对象的任何指针不同,并且与它们的比较表现符合预期,那么您可以侥幸逃脱。
C 标准库中有一些这方面的先例。 <signal.h>
为信号处理程序函数指针定义了三个宏,SIG_DFL
、SIG_ERR
和SIG_IGN
。在某些实现中,这些被定义为常量 -1、0 和 1,转换为适当的指针类型。这些定义不可移植——但由于它们是实现本身的一部分,所以它们不必如此。唯一的要求是它们必须比较不等于任何指向用户定义函数的指针。 (在我使用的实现中,SIG_DFL
恰好是一个空指针;这不是必需的。)
如果库定义了这样的指针,请随意使用。如果失败,则是库中的错误。如果您想自己定义这样的指针,请小心,并了解它可能无法在所有实现上正常工作。
另一种方法是定义适当类型的静态对象,并使用指向该对象的指针:
static some_type foo_obj;
static some_type bar_obj;
const some_type* foo = &foo_obj;
const some_type* bar = &bar_obj;
这是可移植的并且它为您提供的指针值保证与空指针和任何指向用户定义对象的指针不相等。
这是我想了很久的事情。我经常看到人们使用 1 或 -1 作为指针的虚拟值。为了安全需要不同的变量。
这样使用指针可以吗?我想 -1 没问题。但是使用其他负数也可以吗?我可以确定 1 不是已用内存位置吗?如果是这样,我最多可以使用哪个值的内存指针。
P.s。我知道在指针中存储其他数据,尤其是正值,是非常非常糟糕的做法。但我只是想知道在任何现实生活情况下会产生什么后果。
我敢打赌你的编译器会在你这样做时发出警告?这本身应该告诉你这是不好的,应该避免。
许多老旧的代码都有针对值的 NULL(或 nullptr)的保护措施。你把 -1 放在那里,它变成一个无符号的 0xffffffff 地址(32 位域)到那个指针,它会愉快地 运行 尽管你不希望它 运行 的各种事情通过。最好的情况是立即访问冲突/段错误。最坏的情况是没有人注意到,2 个月后事情变得一团糟,你被发现是,好吧...... 'not smart person' 谁非法将非指针值放入指针并炸毁了东西。像这样的错误可能会丢掉工作。
顺便说一句,为什么 'people' 想在指针中使用 1 或 -1?在其中删除 nullptr、NULL 或您的语言支持的任何内容并完成它。否则在那里放一个有效的指针并称之为好。
这取决于您的编译器和(主要)OS——在大多数操作系统上,存在永远无效的地址范围。因此,在这样的 OS 上,可以安全地将诸如 'magic' 值的地址用于永远不会与任何有效对象进行比较的指针。只要您从不取消引用它们,它们就应该没问题——即使您取消引用它,OS 也可以定义行为(通常会抛出特定信号)。
一种更便携的替代方法是创建 'dummy' 全局对象并将指向它们的指针用作您的特殊标记。没有其他有效的对象指针会与虚拟对象指针进行比较,并且虚拟对象的额外开销是最小的。
您可以便携使用的唯一指针值是指向当前存在的对象的指针和空指针。 (我忽略了函数指针和成员指针。)
空指针的目的是拥有一个不指向任何对象的指针值,并且与任何指向对象的指针相比都不相等。该语言只为每种指针类型提供一个这样的指针值。
有时拥有多个不同的指针值会很方便。
您可以自己定义这些值 -- 例如:
const some_type* foo = reinterpret_cast<some_type*>(-1);
const some_type* bar = reinterpret_cast<some_type*>(-2);
严格来说,使用任何一个值,即使不取消引用它,都有未定义的行为。 (我知道 C 就是这种情况;我认为 C++ 也是如此。)但如果您碰巧知道这些值与指向实际对象的任何指针不同,并且与它们的比较表现符合预期,那么您可以侥幸逃脱。
C 标准库中有一些这方面的先例。 <signal.h>
为信号处理程序函数指针定义了三个宏,SIG_DFL
、SIG_ERR
和SIG_IGN
。在某些实现中,这些被定义为常量 -1、0 和 1,转换为适当的指针类型。这些定义不可移植——但由于它们是实现本身的一部分,所以它们不必如此。唯一的要求是它们必须比较不等于任何指向用户定义函数的指针。 (在我使用的实现中,SIG_DFL
恰好是一个空指针;这不是必需的。)
如果库定义了这样的指针,请随意使用。如果失败,则是库中的错误。如果您想自己定义这样的指针,请小心,并了解它可能无法在所有实现上正常工作。
另一种方法是定义适当类型的静态对象,并使用指向该对象的指针:
static some_type foo_obj;
static some_type bar_obj;
const some_type* foo = &foo_obj;
const some_type* bar = &bar_obj;
这是可移植的并且它为您提供的指针值保证与空指针和任何指向用户定义对象的指针不相等。