C++11 中的空指针算法
Void Pointer Arithmetic in C++11
我真的想使用一些无效转换来保存二进制数据,但这要么是 g++ 警告级联,要么是 lot
转换。在 C++(最好是 C++11 或更高版本)中是否有一种简单而安全的方法来进行 void 指针运算?
我只在带有 gnu 编译器的 posix 系统上工作,所以这不是问题。
用例:
我有 void * ptr 到大小 > 1GB 的数据。
我还有其他功能可以做事,让我们称它为stuff()
它的外部库的一部分并获取 (void *, size_t) 作为参数。
stuff(ptr, n) 可能会改变底层内存。基本上我需要传递 ptr*.
的切片
代码应该是,我猜,将不可移植。
如果我找不到更优雅的解决方案,我想我会选择 -Wno-pointer-arithmetics,但答案中提出的解决方案很有帮助
取决于您在询问算术时的想法。以下代码非常好,可以由 GNU g++ -std=c++11 编译:
#include <cstdlib>
#include <cstdio>
int main()
{
void * x = std::malloc(100);
std::printf("%p\n", x);
std::printf("%p\n", x+20);
return 0;
}
(编辑2)
问题很混乱,但是如果要处理 gnu 编译器,则 void 指针算法完全可以。 GNU 基本上将 void * 定义为一个字节递增的指针,因此上面代码中的所有语句都是正确的。我没有用其他编译器测试它,就这个问题而言,我没有必要。
对于 GNU 以外的编译器,使用无符号整数类型完全安全和正确:首先将指针转换为 1 字节整数类型之一:
- size_t
- uintptr_t / intptr_t
- 或者如果您知道内存大小和型号 - 精确的固定宽度整数}
如果每个单元的内存寻址将更改为任何其他奇怪的大小 - 您需要使用在地址添加 +1 后指向下一个物理存储单元的类型。
还要澄清 = bool 不是 1 位类型...它的填充(别名)字符内部有一些包装魔法。
我真的想使用一些无效转换来保存二进制数据,但这要么是 g++ 警告级联,要么是 lot
转换。在 C++(最好是 C++11 或更高版本)中是否有一种简单而安全的方法来进行 void 指针运算?
我只在带有 gnu 编译器的 posix 系统上工作,所以这不是问题。
用例:
我有 void * ptr 到大小 > 1GB 的数据。
我还有其他功能可以做事,让我们称它为
stuff()
它的外部库的一部分并获取 (void *, size_t) 作为参数。stuff(ptr, n) 可能会改变底层内存。基本上我需要传递 ptr*.
的切片
代码应该是,我猜,将不可移植。
如果我找不到更优雅的解决方案,我想我会选择 -Wno-pointer-arithmetics,但答案中提出的解决方案很有帮助
取决于您在询问算术时的想法。以下代码非常好,可以由 GNU g++ -std=c++11 编译:
#include <cstdlib>
#include <cstdio>
int main()
{
void * x = std::malloc(100);
std::printf("%p\n", x);
std::printf("%p\n", x+20);
return 0;
}
(编辑2) 问题很混乱,但是如果要处理 gnu 编译器,则 void 指针算法完全可以。 GNU 基本上将 void * 定义为一个字节递增的指针,因此上面代码中的所有语句都是正确的。我没有用其他编译器测试它,就这个问题而言,我没有必要。
对于 GNU 以外的编译器,使用无符号整数类型完全安全和正确:首先将指针转换为 1 字节整数类型之一:
- size_t
- uintptr_t / intptr_t
- 或者如果您知道内存大小和型号 - 精确的固定宽度整数}
如果每个单元的内存寻址将更改为任何其他奇怪的大小 - 您需要使用在地址添加 +1 后指向下一个物理存储单元的类型。
还要澄清 = bool 不是 1 位类型...它的填充(别名)字符内部有一些包装魔法。