reinterpret_cast
有许多用途可以编译,但都是UB。仅在少数情况下定义良好。目前对我来说很重要的对象正在转换为:
说我有一个缓冲区,其中包含我要解析的二进制结构。我使用的struct
仅包含char a[100]
,并使用方法来提取位于uint32_t
的{{1}}。是否将缓冲区强制转换为结构,然后以这种方式良好地访问结构的数组?
如果是这样,我希望是因为上面的两个规则;但是,我也半信半疑这些规则不适用于a[3]
,或者我可能会遇到某种对齐问题,因为它是一个数组,而不仅仅是char[]
。
一个小的代码示例,以使用例更加清晰:
char*
我想肯定可以简单地将struct Overlay {
char a[100];
uint32_t parseSomeField() const {
return my_char_to_uint32_t_function(&a[3]);
}
};
int main() {
std::vector<char> buffer(1024);
// fill buffer
auto overlay = reinterpret_cast<const Overlay*>(&buffer[0]);
std::cout << overlay->parseSomeField() << std::endl;
}
替换为char a[100]
,但是通过给char *a
设置要解析的结构的大小,可以做到以下几点:好吧:
Overlay
保存一些代码行。
编辑:
多亏了答案和评论,我很清楚Overlay overlay;
// fill overlay by writing into it directly
std::cout << overlay.parseSomeField() << std::endl;
的这种用法是UB。以下支持使用现有缓冲区和并将其直接复制到结构中。您也可以执行reinterpret_cast
,这很好。另外,这应该定义清楚:
sizeof
struct VersatileOverlay {
char a[100];
static uint32_t parseSomeField(const char *a) {
return some_char_to_uint32_t_function(a + 3);
}
uint32_t parseSomeField() const {
return parseSomeField(&a[0]);
}
};
int main() {
std::vector<char> buffer(1024);
// fill buffer
std::cout << VersatileOverlay::parseSomeField(&buffer[0]) << std::endl;
VersatileOverlay vo;
memcpy(&vo, /*source ptr*/, sizeof(VersatileOverlay));
std::cout << vo.parseSomeField() << std::endl;
}
及其兄弟姐妹将简单地调用其静态副本,并将其传递给内部缓冲区。
答案 0 :(得分:2)
是否要强制转换为仅由char []组成的结构并从定义良好的数组中读取?
根据以下规则定义不明确:
[basic.lval]
如果程序试图通过glvalue访问对象的存储值,该glvalue的类型与以下一种类型不相似([conv.qual]),则行为未定义:
- 对象的动态类型,
- 一种类型,它是与对象的动态类型相对应的有符号或无符号类型,或者
- char,unsigned char或std :: byte类型。
当基础对象是#include "stdafx.h"
#include <iostream>
using namespace std;
int squared(int input);
bool pythagCheck(int a, int b, int c);
bool repetitionCheck(int a, int b, int c);
int x;
int increment;
int storeA[1000];
int storeB[1000];
int storeC[1000];
int main()
{
int a = 0, b = 0, c = 0;
//input
cout << "Specify Boundary: ";
cin >> x;
cout << "\n\n";
//function
for (a=0; a<=x; a++)
{
if (pythagCheck(a, b, c) && repetitionCheck(a, b, c))
{
increment++;
storeA[increment] = a;
storeB[increment] = b;
storeC[increment] = c;
}
for (b=0; b<=x; b++)
{
if (pythagCheck(a, b, c) && repetitionCheck(a, b, c))
{
increment++;
storeA[increment] = a;
storeB[increment] = b;
storeC[increment] = c;
}
for (c=0; c<=x; c++)
{
if (pythagCheck(a, b, c) && repetitionCheck(a, b, c))
{
increment++;
storeA[increment] = a;
storeB[increment] = b;
storeC[increment] = c;
}
}
}
}
system("pause");
return 0;
}
int squared(int input)
{
return input * input;
}
bool pythagCheck(int a, int b, int c)
{
if (squared(a) + squared(b) == squared(c) && a != 0 && b != 0 && c != 0)
{
cout << "a = " << a << ", b = " << b << ", c = " << c << endl;
return true;
}
}
bool repetitionCheck(int a, int b, int c)
{
for (int i = 0; i >= increment; i++)
{
if (storeA[i] == b) { return false; }
}
for (int i = 0; i >= increment; i++)
{
if (storeC[i] == c) { return false; }
}
return true;
}
的动态数组时,这些列出的类型都不是Overlay
。
在这里看起来很明智的解决方案只是一个免费的(或静态成员)函数:
char
您可以使用它来解析向量:
std::uint32_t
parseSomeField(const char* a) const {
return my_char_to_uint32_t_function(a + 3);
}
或者,如果您的班级类似于parseSomeField(buffer->data());
:
Overlay