• <tfoot id='QXDG6'></tfoot>
  • <legend id='QXDG6'><style id='QXDG6'><dir id='QXDG6'><q id='QXDG6'></q></dir></style></legend>
      <bdo id='QXDG6'></bdo><ul id='QXDG6'></ul>

    1. <i id='QXDG6'><tr id='QXDG6'><dt id='QXDG6'><q id='QXDG6'><span id='QXDG6'><b id='QXDG6'><form id='QXDG6'><ins id='QXDG6'></ins><ul id='QXDG6'></ul><sub id='QXDG6'></sub></form><legend id='QXDG6'></legend><bdo id='QXDG6'><pre id='QXDG6'><center id='QXDG6'></center></pre></bdo></b><th id='QXDG6'></th></span></q></dt></tr></i><div id='QXDG6'><tfoot id='QXDG6'></tfoot><dl id='QXDG6'><fieldset id='QXDG6'></fieldset></dl></div>

      <small id='QXDG6'></small><noframes id='QXDG6'>

      1. C++结构对齐问题

        时间:2023-09-15

        1. <small id='Auj7g'></small><noframes id='Auj7g'>

          • <bdo id='Auj7g'></bdo><ul id='Auj7g'></ul>
              <tbody id='Auj7g'></tbody>

            • <tfoot id='Auj7g'></tfoot>

                  <legend id='Auj7g'><style id='Auj7g'><dir id='Auj7g'><q id='Auj7g'></q></dir></style></legend>
                  <i id='Auj7g'><tr id='Auj7g'><dt id='Auj7g'><q id='Auj7g'><span id='Auj7g'><b id='Auj7g'><form id='Auj7g'><ins id='Auj7g'></ins><ul id='Auj7g'></ul><sub id='Auj7g'></sub></form><legend id='Auj7g'></legend><bdo id='Auj7g'><pre id='Auj7g'><center id='Auj7g'></center></pre></bdo></b><th id='Auj7g'></th></span></q></dt></tr></i><div id='Auj7g'><tfoot id='Auj7g'></tfoot><dl id='Auj7g'><fieldset id='Auj7g'></fieldset></dl></div>
                1. 本文介绍了C++结构对齐问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  我有一个预定义的结构(实际上有几个),其中变量跨越 32 位字边界.在 Linux(和使用 GCC 的 Windows)中,我能够使用attribute((packed))"将结构打包到正确的大小.但是,我无法使用 VC++ 和 #pragma pack 使其以相同的方式工作.

                  I have a predefined struct (actually several) where variables span across 32-bit word boundary. In Linux (and Windows using GCC) I am able to get my structs to pack to the correct size using 'attribute((packed))'. However I cannot get it to work the same way using VC++ and #pragma pack.

                  使用 GCC 这会返回 6 个字节的正确大小:

                  Using GCC this returns a correct size of 6 bytes:

                  struct
                  {
                      unsigned int   a                : 3;
                      unsigned int   b                : 1;
                      unsigned int   c                : 15;
                      unsigned int   troubleMaker     : 16;
                      unsigned short padding          : 13;
                  } __attribute__((packed)) s;
                  

                  使用 VC++ 会返回错误的 8 字节大小

                  Using VC++ this returns an incorrect size of 8 bytes

                  #pragma pack(push)
                  #pragma pack(1)
                  
                  struct
                  {
                      unsigned int   a                : 3;
                      unsigned int   b                : 1;
                      unsigned int   c                : 15;
                      unsigned int   troubleMaker     : 16;
                      unsigned short padding          : 13;
                  } s;
                  
                  #pragma pack(pop)
                  

                  我可以通过手动跨边界拆分troubleMaker"来使事情发挥作用,但我不想这样做.有什么想法吗?

                  I can get things to work by splitting 'troubleMaker' across the boundary manually but I'd prefer not to. Any ideas?

                  推荐答案

                  疯狂的想法:首先只写一个符合 C99 或 C++03 的程序

                  <小时>

                  我建议不要使用供应商特定的 C 语言扩展来匹配设备或网络位格式.即使您使用一系列每个供应商的语言扩展来排列字段,您仍然需要担心字节顺序,并且您仍然有一个需要额外指令才能访问的结构布局.

                  Crazy idea: just write a C99 or C++03 -conforming program in the first place


                  I would suggest not using vendor-specific C language extensions to match device or network bit formats. Even if you get the fields to line up using a series of one-per-vendor language extensions, you still have byte order to worry about, and you still have a struct layout that requires extra instructions to access.

                  通过使用标准化的 C API 字符串和内存复制函数以及 Posix hton 和 ntoh 函数,您可以编写符合 C99 的程序,该程序可以在任何架构或主机上运行,​​并以最大速度和缓存效率运行.

                  You can write a C99 conforming program that will work on any architecture or host and at maximum speed and cache efficiency by using the standardized C API string and memory copy functions and the Posix hton and ntoh functions.

                  一个好的做法是使用以下已发布标准的函数:

                  A good practice is to use the following functions for which there exist published standards:

                  C99: memcpy(), Posix: htonl(), htons(), ntohl(), ntohs()
                  

                  更新:这里有一些代码应该在任何地方都一样.您可能需要从该项目中获取 如果微软仍然没有为 C99 实现它,或者只是对 int 大小做出通常的假设.

                  Update: here is some code that should work the same everywhere. You may need to get <stdint.h> from this project if Microsoft still hasn't implemented it for C99, or just make the usual assumptions about int sizes.

                  #include <stdlib.h>
                  #include <stdint.h>
                  #include <string.h>
                  #include <stdio.h>
                  #include <arpa/inet.h>
                  
                  struct packed_with_bit_fields {  // ONLY FOR COMPARISON
                      unsigned int   a        : 3;
                      unsigned int   b        : 1;
                      unsigned int   c        : 15;
                      unsigned int   troubleMaker : 16;
                      unsigned short padding  : 13;
                  } __attribute__((packed));       // USED ONLY TO COMPARE IMPLEMENTATIONS
                  
                  struct unpacked { // THIS IS THE EXAMPLE STRUCT
                      uint32_t a;
                      uint32_t b;
                      uint32_t c;
                      uint32_t troubleMaker;
                  }; // NOTE NOT PACKED
                  
                  struct unpacked su;
                  struct packed_with_bit_fields sp;
                  char *bits = "Lorem ipsum dolor";
                  
                  int main(int ac, char **av) {
                    uint32_t x;   // byte order issues ignored in both cases
                  
                    // This should work with any environment and compiler
                    memcpy(&x, bits, 4);
                    su.a = x & 7;
                    su.b = x >> 3 & 1;
                    su.c = x >> 4 & 0x7fff;
                    memcpy(&x, bits + 2, 4);
                    su.troubleMaker = x >> 3 & 0xffff;
                  
                    // This section works only with gcc
                    memcpy(&sp, bits, 6);
                    printf( sp.a == su.a
                        &&  sp.b == su.b
                        &&  sp.c == su.c
                        &&  sp.troubleMaker == su.troubleMaker
                        ? "conforming and gcc implementations match
                  " : "huh?
                  ");
                    return 0;
                  }
                  

                  这篇关于C++结构对齐问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:GCC 中地址清理器的有意义的堆栈跟踪 下一篇:C++ - 获取特定内存地址的值

                  相关文章

                  最新文章

                  • <bdo id='8PVNn'></bdo><ul id='8PVNn'></ul>
                2. <tfoot id='8PVNn'></tfoot>

                    <i id='8PVNn'><tr id='8PVNn'><dt id='8PVNn'><q id='8PVNn'><span id='8PVNn'><b id='8PVNn'><form id='8PVNn'><ins id='8PVNn'></ins><ul id='8PVNn'></ul><sub id='8PVNn'></sub></form><legend id='8PVNn'></legend><bdo id='8PVNn'><pre id='8PVNn'><center id='8PVNn'></center></pre></bdo></b><th id='8PVNn'></th></span></q></dt></tr></i><div id='8PVNn'><tfoot id='8PVNn'></tfoot><dl id='8PVNn'><fieldset id='8PVNn'></fieldset></dl></div>

                  1. <legend id='8PVNn'><style id='8PVNn'><dir id='8PVNn'><q id='8PVNn'></q></dir></style></legend>

                      <small id='8PVNn'></small><noframes id='8PVNn'>