我正在努力通过网络将原始结构发送到另一端的已知程序,但是不得不担心用于对齐结构的静默引入的内存(其他问题如字节顺序被覆盖).我正在使用的是:
typedef struct __attribute__((packed))
{
uint16_t field1;
uint16_t field2;
uint16_t field3;
} packed_1_s;
typedef struct __attribute__((packed))
{
uint16_t fieldA;
uint16_t fieldB;
packed_1_s structArray[10];
} packed_2_s;
typedef struct __attribute__((packed))
{
uint16_t fieldX;
packed_2_s fieldY;
uint8_t arrayZ[20];
} data_s;
Run Code Online (Sandbox Code Playgroud)
我理解通常,packed_1_s结构可以/将为结构的每个实例分配额外的空间,以将其填充到编译器的优选大小(取决于它为其构建的硬件),并且有利的大小可以是2个字节的任何位置到64个字节(最近).通常,如果我在packed_2_s中有一个packed_1_s的单个实例就没有问题,但是当我尝试将元素放入数组时,我会理解它们存在一些差异.
gcc文档似乎建议通过简单地在packed_2_s定义中包含packed属性,即使它们是数组,这些字段也将尽可能紧密地包装,并且不会为packed_2_s结构添加空间以对齐元素数组.关于align()属性的文档虽然表明数组的处理方式与其他字段不同,但需要在字段上直接设置align/packed属性,以便修改添加的额外间距以匹配指定的对齐(或缺少对齐).我尝试在structArray字段上设置packed属性,当它不起作用时,通过在上面的代码中设置arrayZ上的packed属性进行测试:
packed_1_s structArray[10] __attribute__((packed));
uint8_t arrayZ[20] __attribute__((packed));
Run Code Online (Sandbox Code Playgroud)
两次尝试都给了我一个编译器警告,在这个上下文中没有理解packed属性并且会被跳过(我用"-Wall"构建的好东西).
我希望绕过这个问题的方法是使用属性align(1),指示1字节的所需对齐,这与packed属性相当,但是文档说align()属性只能增加对齐和打包应该用于减少对齐.
从我可以从GCC文档中确定的内容来看,似乎有3个主要的附加内存插入案例.
- 结构内容可以具有分配给结构本身的附加存储器以改变字段之间的间隔.
实际上,结构内结构内容的存储器映射的定义可以改变(尽管不是元素的顺序).- 结构可以为其分配额外的内存,以将它们填充到更有效的整体大小.这通常是为了使声明其实例之一之后的其他变量不属于与系统/编译器定义"块"的结构实例相同的"块".
- 无论是否在结构内,数组都可以添加额外的内存以将元素转换为有效对齐.
据我所知,packed属性可用于影响结构并阻止上面案例1和2中添加的额外内存,但似乎没有办法在我的编译器上处理上面的案例3(s ).
有没有办法保证data_s结构绝对没有额外的空间添加到它或它的任何子结构,所以我没有内存映射中的编译器相关的移位?我是否误解了编译器可以插入空间以故意转移内存映射的情况?
我与当地大师讨论了一些问题,听起来我对上面的案例3有一些误解.数组中的元素之间没有插入空格,但保证它们正确对齐的额外空间会添加到结构本身.显然,这表明诸如"sizeof(structureOnlyContaining_uint32_t)"之类的内容并不总是返回"4",因为可能会添加额外的空格来对齐正在使用的编译器上的uint32_t数据类型.结果是真的只有2个案例:
- 结构的存储器映射中的字段之间的较大偏移.
可以修改字段之间的空间以对齐每个字段.这可以使用packed或align()属性进行更改.- 结构末端填充.可以修改sizeof()返回的结构大小,以便最终为系统正确对齐结构的数组.这允许所有系统假设结构的开始始终是对齐的,如果不是则导致问题.这似乎不受pack或align属性的影响.
由于新的情况2,结构中数组的元素不一定遵循结构上指定的packed或align()属性,尽管数组的开头和紧跟在数组之后的字段也是如此.
我的问题是如何处理packed_2_s中的structArray,因为整个数组的大小不能完全由packed属性保证.有没有办法保证structArray字段整体的固定大小?应该注意的是,我不能过多地增加packed_1_s的大小,因为data_s结构需要保持尽可能小(它在流式方案中替换音频/视频数据).
我正在尝试编写一个半便携式 Makefile,它将在没有 MinGW 或 Cygwin 的 Windows 上使用。因此,我几乎必须坚持使用 Windows 提供的标准命令。我知道 UnxUtils,但我想尽可能避免使用它们。此外,如果可以的话,我想避免编写任何特殊的批处理脚本。该解决方案将由对 Linux、Windows 或命令行构建系统不是特别熟悉的人在许多不同的计算机上使用,因此不能依赖环境路径并且不可能进行额外的安装。该解决方案将取代现有系统,该系统严重缺乏一些接近必需的更高级的 make 系统功能,所以我
我遇到的问题与 make 如何解释用作规则一部分的 shell 命令有关。我只是想要echo
一个空行,它也可以作为一些不同规则的一部分重定向到一个文件。在 Windows 中,回显空行的唯一方法是.
在 echo 命令后立即添加一个,不带任何空格:echo.
。当作为规则中的一行提供时,它会导致问题。
some_rule :
@echo.
@echo Text going to file > someFile.txt
@echo. >> someFile.txt
@echo Other text going to a file >> someFile.txt
Run Code Online (Sandbox Code Playgroud)
在提供的示例中,第一行@echo.
和第三行@echo. >> someFile.txt
导致错误:
process_begin: CreateProcess(NULL, echo., ...) failed.
Run Code Online (Sandbox Code Playgroud)
我已经看到一些解释说第三行不应该有空格,而应该是@echo.>> someFile.txt
,但是当我测试它时没有区别。
我很确定这个问题来自这样一个事实,即 make 实现了对隐式 shell 命令的手动查找,并且被检测echo.
为命令而不是echo
. …