匿名结构的无效初始化错误

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

我这里有这个代码:

Void() aba ()
{
}
#define std_Dynamic_Array(T) struct{Int32() count; Int32() capacity; T* memory; }
Void() no_body_func (Int32() b);
Int32() test_func (Int32()*** a)
{
}
Int32() test_func2 (Int32() x)
{
}
Int32() b = 33;
#define v_macro(T) struct{Int32() count; Int32() capacity; T* memory; } v (std_Dynamic_Array(T)* m) \
{ \
    Int32() l = 44; \
}
Void() _main ()
{
    Int64() a = 5;
    b = 22;
    Int32() c = test_func2(6);
    Int32() inner_func (Int32()* a)
    {
        Int32() g = 3;
    }
    Int32()* x = &b;
    inner_func(x);
    Int32() j = *x;
    Float32() f = 33.000000;
    std_Dynamic_Array(Int64()) da = {.count = 4};
    v_macro(Int64());
    std_Dynamic_Array(Int64()) k = v(&da);
}

int main(int argc, char ** argv)
{

    return 0;
}

我正在编写自己的编译器,它可以生成 C 代码作为目标之一。我的问题是我遇到了这个奇怪的错误:

tests/simple.c:34:36: error: invalid initializer
   34 |     std_Dynamic_Array(Int64()) k = v(&da);
      |                                    ^

这是由

gcc -E ...

生成的代码
void aba ()
{
}

void no_body_func (int b);
int test_func (int*** a)
{
}
int test_func2 (int x)
{
}
int b = 33;




void _main ()
{
    long long a = 5;
    b = 22;
    int c = test_func2(6);
    int inner_func (int* a)
    {
        int g = 3;
    }
    int* x = &b;
    inner_func(x);
    int j = *x;
    float f = 33.000000;
    struct{int count; int capacity; long long* memory; } da = {.count = 4};
    struct{int count; int capacity; long long* memory; } v (struct{int count; int capacity; long long* memory; }* m) { int l = 44; };
    struct{int count; int capacity; long long* memory; } k = v(&da);
}

int main(int argc, char ** argv)
{

    return 0;
}

为什么会出现这个错误?

v
的返回类型和
k
的类型都扩展为
struct{int count; int capacity; long long* memory; } 
,那么为什么GCC将它们视为不同的类型呢? 我可以做什么来解决这个问题? 另外:

  1. 我不关心代码的可读性,这是为 GCC 生成的代码,而不是供人类处理的。
  2. 如果解决方案需要人类和语言扩展已知的最黑客的 GCC 技巧,那就这样吧。 C 目标输出的代码将严格与 GCC 一起工作,无需担心 clang、MSVC、ICC 等。

我知道我可能可以通过生成一些 typedef 来解决这个问题,但我想避免这种情况。至少现在是这样。

谢谢!!

c struct compiler-errors compiler-construction
1个回答
0
投票

结构的每个定义都会创建一个独特的类型,这是 C 的一个有意且理想的特性。如果我们有:

typedef struct { double a, b; } GeometricPoint;
typedef struct { double a, b; } ComplexNumber;

然后我们希望

GeometricPoint
ComplexNumber
是不同的类型,这样即使它们的布局相同,也不会意外地将其中一个分配给另一个。

代码中所有

struct{int count; int capacity; long long* memory; }
都有不同的类型,并且每种类型都与其他类型不兼容,因此在尝试将一个类型分配给另一个类型、将一个类型作为参数传递时,您会收到警告和错误对于另一个,或者尝试使用指向它们的指针进行赋值或参数传递。

要解决此问题,请使用标签声明一次结构:

struct MyStructure { int count; int capacity; long long *memory; };

然后在其余代码中仅使用

struct
和标签
struct MyStructure
。或者,您可以使用
typedef
:

typedef struct { int count; int capacity; long long *memory; } MyStructure;

然后在代码的其余部分使用

typedef
名称
MyStructure

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