“Pointer to incomplete class type ‘struct punto’ is not allowed.”

huangapple go评论115阅读模式
英文:

Pointer to incomplete class type "struct punto" is not allowed

问题

I'm trying to create a code that creates a list of points. I have a file named "punti.c" with its header and a file named "item.c" with its header. The problem is that I can't access the variables of the struct point(x,y) from the item.

//item.c
#include <stdio.h>
#include "item.h"
#include "punti.h"

int eq(item it1, item it2)
{
    return it1->x == it2->x; //the problem is here
}
//item.h
#include "punti.h"
typedef Punto item;

int eq(item x, item y);
//punti.c
#include "utilities.h"
#include "punti.h"
#include <math.h>

struct punto
{
    double x;
    double y;
};
//punti.h
typedef struct punto *Punto;

I tested the type Punto in many ways, so I'm sure it works. I tried to change the typedef of item, made it a pointer to Punto, but it didn't work.
(Part of the code is in Italian, sorry:)

英文:

I'm trying to create a code that creates a list of points. I have a file named "punti.c" with its header and a file named "item.c" with its header. The problem is that I can't access the variables of the struct point(x,y) from the item.

//item.c
#include &lt;stdio.h&gt;
#include &quot;item.h&quot;
#include &quot;punti.h&quot;

int eq(item it1, item it2)
{
    return it1-&gt;x == it2-&gt;x; //the problem is here
}
//item.h
#include &quot;punti.h&quot;
typedef Punto item;

int eq(item x, item y);
//punti.c
#include &quot;utilities.h&quot;
#include &quot;punti.h&quot;
#include &lt;math.h&gt;

struct punto
{
    double x;
    double y;
};
//punti.h
typedef struct punto *Punto;

I tested the type Punto in many ways, so I'm sure it works. I tried to change the typedef of item, made it a pointer to Punto, but it didn't work.
(Part of the code is in Italian, sorry:) )

答案1

得分: 1

The header punti.h declares the name Punto as an alias for the pointer type struct punto * to the incomplete type struct punto.

//punti.h
typedef struct punto *Punto;

This header is included in the header item.h where the typedef name item is declared as an alias for the typedef name Punto, which is used in the parameter declaration list of the function eq:

//item.h
#include "punti.h"
typedef Punto item;

int eq(item x, item y);

Both typedef names, Punto and item, still represent pointer types to an incomplete structure type. They can be used in the function declaration because pointers themselves are always complete types.

However, in the module item.c, in the definition of the function eq, expressions are used to access data members of the incomplete structure type struct punto:

//item.c
#include <stdio.h>
#include "item.h"
#include "punti.h"

int eq(item it1, item it2)
{
    return it1->x == it2->x; //the problem is here
}

At this point, the compiler doesn't know if the structure struct punto indeed contains the data member x. Therefore, it issues an error. You need to include the complete structure declaration in modules where there is an attempt to access data members of the structure. Otherwise, the compiler will report errors.

英文:

The header punti.h declares the name Punto as an alias for the pointer type struct punto * to the incomplete type struct punto.

//punti.h
typedef struct punto *Punto;

This header is included in the header item.h where there is declared the typedef name item as an alias for the typedef name Punto that is used in parameter declaration list of the function eq:

//item.h
#include &quot;punti.h&quot;
typedef Punto item;

int eq(item x, item y);

The both typedef names Punto and item still denote pointer types to an incomplete structure type. They may be used in the function declaration because pointers themselves are always complete types.

But then in the module item.c in the definition of the function eq there are used expressions to access data members of the incomplete structure type struct punto

//item.c
#include &lt;stdio.h&gt;
#include &quot;item.h&quot;
#include &quot;punti.h&quot;

int eq(item it1, item it2)
{
    return it1-&gt;x == it2-&gt;x; //the problem is here
}

AT this point the compiler does not know whether indeed the structure struct punto contains the data member x. SO it issues an error. You need to include the complete structure declaration in modules where there are attempt to access data members of the structure. Otherwise the compiler will report errors.

答案2

得分: 0

The definition of struct punto needs to be known to item.c (f.e. included with punti.h).

你需要在item.c中知道struct punto的定义(例如通过punti.h包含)。

You can think about typedef as an alias. "The typedef declaration provides a way to declare an identifier as a type alias, to be used to replace a possibly complex type name" (cppreference). The compiler pretty much just replaces typedef with what it defines. Your function is then equivalent to:

你可以将typedef视为别名。 "typedef声明提供了一种将标识符声明为类型别名的方式,用于替代可能复杂的类型名称"(cppreference)。编译器基本上只是用其定义替换typedef。然后,您的函数等效于:

int eq(struct punto* it1, struct punto* it2)
{
    return it1->x == it2->x;
}

Because of that, it needs to know the definition of struct punto.

因此,它需要知道struct punto的定义。

If you don't want the definition of struct punto to be known, you need to provide an alternative way of accessing its members. f.e.:

如果您不希望知道struct punto的定义,您需要提供访问其成员的替代方法。例如:

Stack overflow - what defines an opaque type in c

Stack Overflow - C中什么定义了不透明类型

//punti.h
typedef struct punto *Punto;
double get_x(Punto p);
//punti.c
...
struct punto
{
    double x;
    double y;
};

double get_x(Punto p)
{
    return p->x;
}
//item.c
...
int eq(item it1, item it2)
{
    // This is ok, as there is no `->` or `*it1`.
    return get_x(it1) == get_x(it2);
}

感谢@Someprogrammerdude的想法。

英文:

The definition of struct punto needs to be known to item.c (f.e. included with punti.h).

// punti.h
struct punto
{
    double x;
    double y;
};

typedef struct punto *Punto;

You can think about typedef as an alias. "The typedef declaration provides a way to declare an identifier as a type alias, to be used to replace a possibly complex type name" (cppreference). The compiler pretty much just replaces typedef with what it defines. Your function is then equivalent to:

int eq(struct punto* it1, struct punto* it2)
{
    return it1-&gt;x == it2-&gt;x;
}

Because of that, it needs to know the definition of struct punto.


If you don't want the definition of struct punto to be known, you need to provide an alternative way of accessing its members. f.e.:

Stack overflow - what defines an opaque type in c

//punti.h
typedef struct punto *Punto;
double get_x(Punto p);
//punti.c
...
struct punto
{
    double x;
    double y;
};

double get_x(Punto p)
{
    return p-&gt;x;
}
//item.c
...
int eq(item it1, item it2)
{
    // This is ok, as there is no `-&gt;` or `*it1`.
    return get_x(it1) == get_x(it2);
}

Thank you @Someprogrammerdude for the idea.

huangapple
  • 本文由 发表于 2023年3月31日 16:08:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75896230.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定