在C中:
struct __attribute__((scalar_storage_order("big-endian"))) test_struct{
int a;
int b;
int c;
};
struct test_struct test1 = {1,1,1};
struct test_struct test2[3] = {{1,1,1},{1,1,1},{1,1,1}};
void func1(int *arg);
void func2(struct test_struct *arg);
int main()
{
func1(&test1.a);
func2(&test2[1]);
return 0;
}
void func1(int *arg){};
void func2(struct test_struct *arg){}
对 func1 的调用导致 GCC (Linux) 错误“无法采用反向存储顺序获取标量的地址” 而对 func2 的调用则按预期编译并执行。
这只是一个简单的示例,演示了我在更大的代码库中遇到的问题,该代码库因专有原因无法发布。
代码库是双目标,其中目标的字节序不同,因此对大字节序目标版本进行了 scalar_storage_order 修改。 GCC 版本 8.5.0
我正在努力理解 scalar_storage_order 如何在“底层”工作,为什么我可以传递包含逆序标量变量的结构的地址,但我无法传递逆序标量变量本身的地址?记忆是如何组织起来创造这两个条件的?
有关字节顺序的维基百科页面告诉您一些背景知识。
无论如何,简单来说,在您的情况下,字节序意味着存储跨多个内存单元的值的顺序。
这是一个简单的测试程序,可能不符合标准:
#include <stdio.h>
static void dump(unsigned char *p, size_t l) {
while (l > 0) {
printf("%02X", *p);
p++;
l--;
}
puts("");
}
int main(void) {
struct __attribute__((scalar_storage_order("big-endian"))) {
int v;
} be = { 0x12345678 };
struct __attribute__((scalar_storage_order("little-endian"))) {
int v;
} le = { 0x12345678 };
dump((unsigned char *)&be, sizeof be);
dump((unsigned char *)&le, sizeof le);
return 0;
}
在我的系统(带有较旧 MinGW 的 Windows 10)上,该程序打印:
12345678
78563412
因此错误提醒您检查引用值的字节序。正如你从实验中看到的,它试图阻止你产生误解。
test1.a
是默认值 int
的反向字节序值。