问题标签 [pragma-pack]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
491 浏览

c++ - 编译时间检查 #pragma pack 的使用情况

大多数编译器支持通过使用#pragma pack(N)指令来更改类的打包,其中N是每个成员的新的最小可接受对齐方式。

是否可以在编译时检查是否#pragma pack(N)已指定 a。另外,有没有办法确定N

0 投票
2 回答
237 浏览

c - 如果结构仅包含字节数组,那么 `#pragma pack(1)` 是否有风险/危险

#pragma pack(1)在仅包含字节数组的结构上使用是否危险/有风险?例如这个:

(想法是将此结构直接转换为/从 2^16 原始 I/O 字节转换,而不会出现任何不兼容甚至错误)

0 投票
2 回答
2946 浏览

c - 将结构复制到字节数组中

我在 C 中有一个 1 字节的编译指示压缩结构,我想将其复制到一个字节数组中,以便通过串行端口发送序列化。

将它序列化为字节数组的最佳方法是什么,我应该使用memcpy()吗?

还是更好地使用逐字节复制进行指针类型转换?

0 投票
1 回答
443 浏览

c++ - 没有相应弹出的 pragma pack(push) 导致堆栈粉碎

#pragma pack(push, 2)在头文件中结构的开头使用但忘记了相应的#pragma pack(pop). 包含这个头文件后,我包含了 fstream. 在创建ofstream对象时,我看到堆栈粉碎。确切的场景和代码的详细信息如下。

我正在学习 C++ 课程并为该项目编写了代码。我的程序由于堆栈粉碎而崩溃。我试图寻找任何明显的溢出错误,但找不到。我更改了几乎所有的代码以类似于讲师提供的代码。唯一的区别是包含的头文件的顺序。我已经包含了我的头文件,然后fstream教练fstream在顶部包含了头文件。我仍然遇到同样的问题。所以我什至改变了头文件的顺序,瞧,问题就消失了。

由于这对我来说很奇怪,我试图在我的代码中本地化这个问题。
我在整个代码中插入了打印语句,以查找发生堆栈粉碎的函数。

在找到函数时,我使用 gdb 设置监视程序使用的金丝雀值以检查堆栈粉碎。我在对象的构造函数中检测到堆栈粉碎ofstream

此时我知道之前包含的一些头文件fstream正在干扰它。所以现在我检查了我所有的头文件是否有任何愚蠢的错误,发现一个结构体前面#pragma pack(push, 2)没有对应的#pragma pack(pop). 该结构将被编写为二进制文件。纠正这个问题解决了这个问题。

由于整个项目无关紧要,我用一个简单的代码片段重现了这个问题。虽然问题解决了,但我想知道为什么会这样。我知道该pragma pack指令用于防止编译器在结构内插入填充,因为必须将结构写入二进制文件。省略pack(pop)结构末尾的 ,对所有后续头文件使用相同的。但这会导致 ofstream 构造函数写入堆栈帧之外吗?

我在 Ubuntu 18.04 上使用 gcc v7.4.0。

头文件

0 投票
1 回答
202 浏览

c++ - 使用 pragma pack 时 wcslen() 返回不正确的结果

我发现当源是 wchar_t 数组(打包结构的成员)时,wcslen() 在 gcc 上返回不正确的结果(并且在 msvc 上正确)。我知道在 linux sizeof(wchar_t) == 4 和 windows 上它的 2 但仍然无法理解打包如何影响 wcslen() 函数。如果我将 wchar_t/wcslen 更改为 char/strlen 它会按预期工作。

为什么用 gcc 编译的这段代码返回 7?它应该返回 8(就像 msvc 一样)。顺便说一句,复制的字节是正确的(b.buf[7] == '6')。

0 投票
1 回答
253 浏览

c++ - #pragma pack(1) 导致分段错误

在某些时候,我的大项目的代码开始使用这样的堆栈跟踪出现分段错误运行时错误:

0# std::basic_ios >::widen (__c=10 '\n', this=) at /usr/include/c++/7/bits/basic_ios.h:450
1# std::endl > (__os=. ..) at /usr/include/c++/7/ostream:591
2# std::ostream::operator<< (__pf=, this=) at /usr/include/c++/7/ostream:113
3# main () 在 segfault.cpp:11

last (3#) 总是指向std::cout行,例如std::cout << "hello" << std::endl;

所以我把我的代码放到这个最小的结构中,它仍然会导致同样的错误:

这是用g++ -std=c++17 segfault.cpp -o segfault -g -Ofast命令构建的。

执行以下任何操作都会取消错误:

  • 去除#pragma pack(1)
  • -Ofastg++选项中删除
  • 移除for(;;){std::cout ...移出循环)
  • 前移#include <iostream>_#pragma pack(1)

尝试使用g++ 7.4.0g++ 9.2.1构建(结果相同)。

0 投票
2 回答
166 浏览

c - 为什么#pragma pack 也会影响结构自身的对齐方式?

我注意到,当在结构周围使用#pragma pack 时,它内部的对齐方式不仅受到影响,而且结构本身的对齐方式也会发生变化。考虑以下:

你可以试试这个代码在这里:https ://onlinegdb.com/BkebdxZEU

程序返回Address 601041 rem 1,这意味着编译指示也对结构产生了对齐(1)的影响。

这是为什么?这是定义的行为吗?

0 投票
1 回答
302 浏览

c++ - MSVC 与 clang/gcc 上的结构字节布局(#pragma pack 行为)不同

以下代码在 MSVC 与 clang/gcc 上的内存中生成不同的布局。为什么?

MSVC x64 上的输出是:

Linux下clang x64上的输出为:

如何让 clang 布局与 MSVC 布局相匹配?

0 投票
2 回答
134 浏览

c - 用于 IAR 编译器内联函数的 C 宏

使用以前的 gcc 编译器,我们这样做了:

所以实际上意味着 PACK_ON(2) 将扩展为 _Pragma(pack(2)) 然后我们会像这样使用它

但是,IAR 编译器想要这样的东西: _Pragma("pack(2)") 所以我尝试通过以下非编译方式来实现 pack 的宏:

有没有人有一个宏可以与 IAR 编译器一起使用来打包各种大小的 n ?如果不是,我将强制所有内容打包大小 1 并手动更改使用 2 和 4 的结构。

临时解决方案:我已经设法通过这样做来解决这个问题:

并手动更改 PACK_ON(2) 和 PACK_ON(4) 的一小部分

0 投票
1 回答
45 浏览

c++ - 如何正确对齐结构?

我正在尝试使用指令(#pragma pack)对齐结构。

我需要它的大小为 112 字节。(14*8=112 字节)。

但是它只有 80 个字节。

如何正确执行?

非常感谢!!