【问题标题】:Is it possible to cast to fixed sized array in cpp?是否可以在 cpp 中转换为固定大小的数组?
【发布时间】:2021-01-07 15:58:49
【问题描述】:

我不知道这是可能的,可能不是 - 但也许

我想要达到的效果如下,仅适用于n 大小的字符数组:

*(__int64*)(address) = 0x1337;

这适用于__int64__int32float 以及更多类型,我想做的是

*(char[8]*)(address) = [0x37, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];

【问题讨论】:

  • 这是你想要的吗? stackoverflow.com/a/35745703/2602718
  • 确实如此,但我想通过强制转换而不是 memcpy 来实现
  • 强制转换将成为未定义行为的路径; std::memcpy 是支持这种恶作剧的方式。
  • 要转换为指向数组的指针,可以使用(char (*)[8])address。但不要。
  • 您能说明一下您想了解什么语言吗?尽管它似乎与汇编语言没有任何关系,但它同时被标记为 c++assembly,并且在您的评论中您提到 C 是第三种语言。

标签: c++ arrays pointers assembly char


【解决方案1】:

是否可以在 cpp 中转换为固定大小的数组?

不,在 C++ 中不能强制转换为数组类型。但是您可以转换为指向数组的指针,我猜这可能是您想要做的。

*(char[8]*)(address)

我想您正在尝试将address 转换为指向数组的指针。这不是指向数组的指针的正确语法。这是正确的:*(char(*)[8])(address)

另一个问题是数组不可赋值。您可以做的是分配数组的每个元素。有标准算法可以做这样的循环。在这种情况下,一个简单的解决方案是声明一个包含这些元素的数组,然后从该数组复制到address 指向的那个。示例:

char* ptr = *static_cast<char(*)[8]>(address);
constexpr std::array data{0x37, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
std::copy(std::begin(data), std::end(data), ptr);

分配数组的一种方法是将它们包装在一个类中,并使用该类的赋值运算符。事实上,上面例子中使用的std::array模板正是这样的包装器。如果您将该类型用于原始数组,那么您可以简单地执行以下操作:

std::array<char, 8> array;
void* address = &array; // imagine that for some reason you are forced to use void*

*static_cast<std::array<char, 8>*>(address)
    = {0x37, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

附:避免 C 风格的强制转换。

【讨论】:

  • data 可以是conststatic const,这可能有助于编译器不那么笨拙,实际上可以立即存储。虽然希望编译器会在启用优化的情况下解决这个问题。
  • @PeterCordes 更好的是:constexpr
  • 你说*(char(*)[8])(address) = ....“是正确的”。但是不支持数组赋值,只支持初始化。所以该表达式的= 部分实际上是不正确的。如果您想违反严格别名并实际分配,您需要一个 struct { char a[8]; }; 并且需要在 RHS 上进行强制转换或其他东西来创建正确类型的适当匿名对象。 (在 C 中,您可以通过强制转换来做到这一点)。或者,如果可行的话,也可以转换为对std::array 的引用?
  • @DanielCohen 这是 C++,不是 C
  • 是的,我的意思是 c++17
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-01
  • 2019-03-14
  • 1970-01-01
  • 2013-06-16
  • 2016-10-29
相关资源
最近更新 更多