GCC scalar_storage_order 属性

问题描述 投票:0回答:1

在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 如何在“底层”工作,为什么我可以传递包含逆序标量变量的结构的地址,但我无法传递逆序标量变量本身的地址?记忆是如何组织起来创造这两个条件的?

c gcc struct embedded endianness
1个回答
0
投票

有关字节顺序的维基百科页面告诉您一些背景知识。

无论如何,简单来说,在您的情况下,字节序意味着存储跨多个内存单元的值的顺序。

这是一个简单的测试程序,可能不符合标准:

#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
的反向字节序值。

© www.soinside.com 2019 - 2024. All rights reserved.