GCC scalar_storage_order属性

9wbgstp7  于 2023-11-17  发布在  Scala
关注(0)|答案(1)|浏览(115)

在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){}

字符串
对func 1的调用会导致GCC(Linux)错误“无法以相反的存储顺序获取标量地址”,而对func 2的调用会按预期编译和执行。
这只是一个简单的例子,演示了我在一个更大的代码库中遇到的问题,由于专有原因,这些代码库无法发布。
代码基础是双目标,其中目标的字节序不同,因此对big-endian目标版本进行了scalar_storage_order修改。GCC版本8.5.0
我一直在努力理解scalar_storage_order是如何“隐藏”工作的,为什么我可以传递一个包含逆序标量变量的结构体的地址,但我不能传递逆序标量变量本身的地址?内存是如何组织起来创建这两个条件的?

deikduxw

deikduxw1#

Wikipedia page about endianness告诉你一些背景。
无论如何,在简单的话和你的情况下,endianness意味着存储跨越几个存储单元的值的顺序,这里是多个字节的int s。
这是一个简单的测试程序,可能不符合标准:

#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;
}

字符串
在我的系统上(Windows 10和较旧的MinGW)这个程序打印:

12345678
78563412


所以这个错误提醒你检查引用值的字节序。正如你在实验中看到的,它试图阻止你误解。test1.a是一个与默认值int相反的字节序。

  • 注意事项:此属性仅适用于结构和联合,并且仅对标量类型和数组有效,而不是对所有目标有效。

相关问题