变体类型存储和对齐问题

发布于 2024-10-25 20:46:55 字数 808 浏览 3 评论 0原文

我创建了一个变体类型来代替 boost::variant。我的工作是将当前类型的索引存储在可能类型的列表中,并将数据存储在具有足够空间来存储最大类型的字节数组中。

unsigned char data[my_types::max_size];
int type;

现在,当我向这个变体类型写入值时,麻烦就来了。我使用以下代码:

template<typename T>
void set(T a) {
   int t = type_index(T);
   if (t != -1) {
      type = t;
      puts("writing atom data");
      *((T *) data) = a; //THIS PART CRASHES!!!!
      puts("did it!");
    } else {
      throw atom_bad_assignment;
    }
}

崩溃的行是将数据存储到内部缓冲区的行。正如您所看到的,我只是将字节数组直接转换为所需类型的指针。当我尝试写入一些值时,这会给我带来错误的地址信号和总线错误。

我在 64 位系统上使用 GCC。如何设置字节数组的对齐方式以确保数组的地址是 64 位对齐的? (或者与我可能将此项目移植到的任何架构正确对齐)。

编辑:谢谢大家,但错误在其他地方。显然,英特尔并不真正关心对齐。对齐的东西会更快,但不是强制性的,并且程序以这种方式运行良好。我的问题是我在写入内容之前没有清除数据缓冲区,这给某些类型的构造函数带来了麻烦。但是,我不会将问题标记为已回答,以便更多人可以给我有关对齐的提示;)

I've made a variant type to use instead of boost::variant. Mine works storing an index of the current type on a list of the possible types, and storing data in a byte array with enough space to store the biggest type.

unsigned char data[my_types::max_size];
int type;

Now, when I write a value to this variant type comes the trouble. I use the following:

template<typename T>
void set(T a) {
   int t = type_index(T);
   if (t != -1) {
      type = t;
      puts("writing atom data");
      *((T *) data) = a; //THIS PART CRASHES!!!!
      puts("did it!");
    } else {
      throw atom_bad_assignment;
    }
}

The line that crashes is the one that stores data to the internal buffer. As you can see, I just cast the byte array directly to a pointer of the desired type. This gives me bad address signals and bus errors when trying to write some values.

I'm using GCC on a 64-bit system. How do I set the alignment for the byte array to make sure the address of the array is 64-bit aligned? (or properly aligned for any architecture I might port this project to).

EDIT: Thank you all, but the mistake was somewhere else. Apparently, Intel doesn't really care about alignment. Aligned stuff is faster but not mandatory, and the program works fine this way. My problem was I didn't clear the data buffer before writing stuff and this caused trouble with the constructors of some types. I will not, however, mark the question as answered, so more people can give me tips on alignment ;)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我的黑色迷你裙 2024-11-01 20:46:55

请参阅 http://gcc.gnu.org/onlinedocs/ gcc-4.0.4/gcc/Variable-Attributes.html

unsigned char data[my_types::max_size] __attribute__ ((aligned));
int type;

See http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Variable-Attributes.html

unsigned char data[my_types::max_size] __attribute__ ((aligned));
int type;
甜中书 2024-11-01 20:46:55

我相信

#pragma pack(64)

适用于所有现代编译器; 它绝对适用于 GCC

更正确的解决方案(不会扰乱全局打包)是:

#pragma pack(push, 64)
// define union here
#pragma pack(pop)

I believe

#pragma pack(64)

will work on all modern compilers; it definitely works on GCC.

A more correct solution (that doesn't mess with packing globally) would be:

#pragma pack(push, 64)
// define union here
#pragma pack(pop)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文