C header files #include statements and dependencies - c

This is a question that I have been reading a lot about but I am still unclear how things work as I am getting building errors or incomplete type lint errors.
I have a project requiring opengl that I am writing low level opengl function, then I want to build on top of those translation [here after referred to as TU] units to build more higher level TU.
for example.
I have a common_structs.h that defines a few things like this:
common_structs.h
#ifndef COMMON_STRUCTS_H
#define COMMON_STRUCTS_H
#include <OpenGL.h>
struct renderable_2D {
...
float angle;
GLshort vertex_count;
GLfloat vertices[12];
GLfloat colors[16];
GLshort indices[6];
GLfloat tex_coords[8];
...
};
struct texture_2D {
...
GLuint texture_id;
...
};
struct default_shader {
const char* vertex_shader_srouce;
const char* fragment_shader_source;
GLuint shader_program;
};
struct camera_2D {....};
#endif /* COMMON_STRUCTS_H */
I declared these structs in their own header file to avoid circular dependencies.
This file isn't compiled but I need to #include opengl to clear the lint warnings for the GLtypes.
Next up there are header and source TU that implement the functionality for these types. Typically
Let's look at renderable_2D for example:
#ifndef RENDERABLE_2D_H
#define RENDERABLE_2D_H
#include "../../common/common_structs.h" //include the definition of renderable_2d
struct renderable_2D* ren2d_new(void);
struct renderable_2D* ren2d_set_uv(struct renderable_2D* out, const float uv[]);
struct renderable_2D* ren2d_set_tint(struct renderable_2D* out, const float r,
const float g, const float b,
const float a);
struct renderable_2D* ren2d_set_alpha(struct renderable_2D* out, const float a);
struct renderable_2D* rend2d_set_z_index(struct renderable_2D* out,
const int index);
struct renderable_2D* rend2d_set_angle(struct renderable_2D* out,
const float angle);
#endif /* RENDERABLE_2D_H */
and the some of the source file for this:
#include "../headers/renderable_2D.h"
#include <stdlib.h>
this file includes the header and implement the functions. Next there's one more header only file.
core_graphics.h
#ifndef CORE_GRAPHICS_H
#define CORE_GRAPHICS_H
#include "renderable_2D/headers/renderable_2D.h"
#include "default_shader/headers/default_shader_2D.h"
#include "default_camera_2D/headers/default_camera_2D.h"
#endif /* CORE_GRAPHICS_H */
this is a header only TU again and will include all the sub TU that make up this part of the library. It's supposed to be built as a shared library so next up the ladder is another shared library that will
#include core_graphics/core_graphics.h
this is where the problem comes in. Say I have another TU main.c, main looks like this.
main.c
#include "core_graphics/core_graphics.h"
#include <stdlib.h>
int main(int argc, char* argv[])
{
struct renderable_2D* rend = (struct renderable_2D*)calloc(1, sizeof(struct renderable_2D));
return 0;
}
the line where I try to calloc the struct I get lint errors saying
invalid application of 'sizeof' to an incomplete type 'struct renderable_2d'
now incomplete types says it cant find the definition of the struct renderable_2D but, from the source listed above, should it get included?
core_graphics.h has the definition of common_structs.h which holds the definition of the struct?
struct renderable_2D --> common_structs.h --> core_graphics.h --> main.c

Related

Cant send pointer to structure after it moved to a different header file

I have a program spread through 3 different C files, with the 2 header files that come with it. I originally had the header "Player.h" that I used to save the "map" structure (among others):
#ifndef PLAYER_H_INCLUDED
#define PLAYER_H_INCLUDED
typedef struct map{
float x;
float y;
}map;
/// some other functions and structures///
#endif
I wanted to move it to its own header file, "Map.h" so its with the other map-related functions and structures.
#ifndef MAP_H_INCLUDED
#define MAP_H_INCLUDED
typedef struct map{
float x;
float y;
}map;
#endif
I made the Map.c file as normal, wrote a function in it that would work, but I didn"t call for the function in main.c yet.
I made the "map" data structure in main.c as followed:
#include "Player.h"
#include "Map.h"
int main(){
... /// some other stuff being done
map map;
map.x = 0;
map.y = 0;
... /// more stuff being done
callfunctioninplayer(&map, /// other variables///)
}
so I call the function in player.c, where I also included map.h using #included "Map.h". But after trying to compile it, it gave me an error everywhere where I asked for the map* map structure with the errors:
In file included from ./main.c:10:0:
./Player.h:21:55: error: unknown type name ‘map’
void movementPlayer(int* inputPlayer, player* player, map* map, unsigned int countFrames);
./Player.h:21:55: error: unknown type name ‘map’
void movementPlayer(int* inputPlayer, player* player, map* map, unsigned int countFrames);
^~~
In file included from ./Map.c:10:0:
./Player.h:21:55: error: unknown type name ‘map’
void movementPlayer(int* inputPlayer, player* player, map* map, unsigned int countFrames);
I checked if map.h was defined everywhere, it is, and I tested it again after putting the map struct back in player.h. Putting it back in player.h worked, but why didn't it in map.h?
I'm sorry if this is asked a lot, I looked through some posts but couldn't find anyone with the same error
It looks like map is being used in Player.h, but Map.h hasn't been included at the point Player.h is included, and presumably you didn't include Map.h in Player.h.
If Player.h needs definitions in Map.h, then you need to #include "Map.h" in Player.h.

How to use a function of a struct in another struct?

i'm doing a simple project in C in which, for the moment, i use two structs: Player and Card.
I have created the 2 struct in different header files, because functions in Player use Card, but also other elements that I haven't already done.
When I try to use getId() in Player, the VSCode's compiler says:
reference to external symbol _getId not resolved in _discardCard()
card.h code is:
#include <stdbool.h>
typedef struct card{
int id;
bool black;
int numElems;
char* text[3];
}card;
card* initCard(int id,bool black,char* text[],int numElems)
int getId(card* c);
card.c code is:
#include "carta.h"
#include<stdio.h>
#include <stdbool.h>
#include <stdlib.h>
...
int getId(carta* c){
return c->id;
}
Instead the code for Player.h is:
#include "card.h"
#define CARDSMAX 5
typedef struct{
bool master;
int id;
int points;
char* nickname;
card* cards[CARDSMAX];
int NumCards;
}player;
... //other functions
card* discardCard(int id,player* g);
The code for Player.c is:
#include "player.h"
#include <stdio.h>
#include <stdlib.h>
player* initPlayer(char* nickname,int id){
player* g=(player*) malloc(sizeof (player));
g->id=id;
g->nickname=nickname;
g->master=false;
g->points=0;
g->NumCards=0;
for(int i=0;i<CARDSMAX;i++){
g->cards[i]=(card*)malloc(sizeof(card));
}
return g;
}
....
card* DiscardCard(int id,player* g){
for(int i=0;i<CARDSMAX;i++){
card* c=g->cards[i];
if(getId(c)==id){
card* e= g->cards[i];
g->cards[i]=NULL;
g->NumCards--;
return e;
}
}
return NULL;
}
Can someone help me? (If you see some inconsistency in the code, it'is because i tried a fast translation from my language)
So, as suggested , the problem was that in Windows' compiler, when you use struct that use function defined in other structs,it is required to pass the .obj file during the compilation .
For doing this you need to compile every .c file that is used by others singulary and then link the .obj file created in this fase.
So in my case the first step is to compile:
cl card.c
that create a card.obj (the Windows' compiler could show you a message that says something like:"The start point is not indicated" if you don't use a main in this first file, don't worry and carry on with this procedure) and then I compile:
cl player.c /link card.obj
So in this way you pass the compiled object in which it's provided the implementation of all the function in the struct.

How to get a typedef struct to work across multiple files files? error: invalid use of undefined type 'struct data'

The struct declaration in my main.c file. I have the function prototype declared but not shown.
typedef struct data
{
int t;
float tp, tf, tt;
} reactorData;
int main()
{
reactorData reactorOne[21];
//other stuff
}
This is the function giving me errors in my function.c file. Specifically in the printf() statement.
typedef struct data reactorData; //this is what I have up top
void reactorOutput(reactorData * data)
{
int c;
for (c=0;c<21;c++)
{
printf(" %3d\t %.0f\t %.0f\t %.0f\n",c, data[c].tp, data[c].tf, data[c].tt);
}
}
The error reads:
|error: invalid use of undefined type 'struct data'|
The function itself works perfectly fine/ I've tested it within main. Its only when I have it in functions.c it doesn't work.
New structs and type definition that must be shared across different compile units are best placed in a header file:
// mystructh.h
#ifndef MYSTRUCT_H
#define MYSTRUCT_H
typedef struct data
{
int t;
float tp, tf, tt;
} reactorData;
void reactorOutput(reactorData * data);
// other stuff
#endif
then in the other c files you have to include the header
main.c
#include <stdio.h>
#include "mystruct.h"
int main(void)
{
reactorData reactorOne[21];
// for example
reactorOutput(reactorOne);
//other stuff
}
functions.c
// functions.c
#include "mystruct.h"
void reactorOutput(reactorData * data)
{
int c;
for (c=0;c<21;c++)
{
printf(" %3d\t %.0f\t %.0f\t %.0f\n",c, data[c].tp, data[c].tf, data[c].tt);
}
}
The problem with your version is that struct data is only defined in main.c.
When the compiler compiles functions.c, it doesn't know what struct data is.
That's why you have to use header files live shown above.

Calling Struct to main function from header file

I have two header files and a main program.
Header files are data.h and flight.h. The main program is calculateflight.c.
The data header file has a set of typedef structs that contains the variables required for the program to run.
I have created a headerfile named flightmodel.h that contains the following:
#ifndef __FLIGHT_MODEL_H
#define __FLIGHT_MODEL_H
#include "Data.h"
void calculateFlight(speedParamsType *speed, spinParamsType *spin,
flightParamsType *fData);
#endif
The data.h contains typedef structs like
typedef struct {
float totalSpin;
float spinAxis;
float backSpin;
float sideSpin;
} spinParamsType;
There are no errors in the struct variables, but I don't know how to call struct inside the main function.
void main()
{
speedParamsType speed;
spinParamsType spin;
flightParamsType fData;
speed.totalSpeed=200.0f;
speed.launchAngle=30.0f;
speed.horizontalAngle=5.0f;
spin.totalSpin=1000.0f;
flightParamsType fData;
fData.carry=
calculateFlightModel(&speed,&spin,&fData);
getch();
}
This is what i have done in the main function.It shows error C2275: 'flightParamsType' : illegal use of this type as an expression
see declaration of 'flightParamsType';
syntax error : missing ';' before identifier 'fData'
Here's one example of usage, note that besides the #include directive, there's nothing special that needs to be done.
#include "flight.h"
int main(int argc, char *argv[])
{
spinParamsType a = {1.0f, 1.0f, 1.0f, 1.0f};
spinParamsType b = {2.0f, 2.0f, 2.0f, 2.0f};
flightParamsType c; // I don't know what kind of members this struct have.
calculateFlight(&a, &b, &c);
return 0;
}
Remember to compile all the source code files and link them together
You have an extra, duplicate declaration of flightParamsType fData between the statements:
spin.totalSpin=1000.0f;
flightParamsType fData;
fData.carry=
calculateFlightModel(&speed,&spin,&fData);
(in addition to the one near the beginning of main). That's illegal.

How to solve Undefined Struct in C?

I've been at this for several days now, unable to compile successfully. I made a very-oversimplified project separate from my main one. Depending which embeded struct I comment out, I get one of the following errors:
file: x2d_gfx_speech_balloon.h
error C2079: 'sprBalloon' uses undefined struct 'X2D_SPRITE'
error C2079: 'font' uses undefined struct 'X2D_FONT'
Side note: Putting the sprite and font headers from the common header into the speech balloon header itself has no effect either.
I'm going to provide the entire simplified code below. Please let me know if you see any syntax wrong, and optionally, feel free to compile it on your side if it helps. My environment is Windows 7 with Visual Studio 2010 and using C89.
main.c
#include "common.h"
int main(void)
{
return 0;
}
common.h
#ifndef _COMMON_H_
#define _COMMON_H_
#include <stdio.h>
#include <stdlib.h>
#include "constants.h"
#include "X2D_GFX_Sprite.h"
#include "X2D_GFX_Font.h"
#include "X2D_GFX_Speech_Balloon.h"
#endif
constants.h
#ifndef _CONSTANTS_H_
#define _CONSTANTS_H_
/* General Constants */
#define TRUE 1
#define FALSE 0
#endif
X2D_GFX_Font.h
#ifndef _X2D_GFX_FONT_H_
#define _X2D_GFX_FONT_H_
#include "common.h"
/* Font Structure */
struct X2D_FONT
{
float x, y;
int size;
int blnShow;
};
/* Font Prototypes (not shown here)... */
int fnt_init(struct X2D_FONT *objFont, const char *strFileName,
const char *strText, const float x, const float y,
const unsigned int size);
#endif
X2D_GFX_Font.c
#include "X2D_GFX_Font.h"
int fnt_init(struct X2D_FONT *objFont, const char *strFileName,
const char *strText, const float x, const float y,
const unsigned int size)
{
return TRUE;
}
X2D_GFX_Sprite.h
#ifndef _X2D_GFX_SPRITE_H_
#define _X2D_GFX_SPRITE_H_
#define MAX_VARSI 10
#include "common.h"
struct X2D_SPRITE
{
float x;
float y;
unsigned int width;
unsigned int height;
int blnShow;
float vx, vy;
float angle;
int varsi[MAX_VARSI];
};
int spr_init(struct X2D_SPRITE *spr, const char *strFileName);
#endif
X2D_GFX_Sprite.c
#include "X2D_GFX_Sprite.h"
int spr_init(struct X2D_SPRITE *spr, const char *strFileName)
{
return TRUE;
}
X2D_GFX_SPEECH_BALLOON.h
#ifndef _X2D_GFX_SPEECH_BALLOON_H_
#define _X2D_GFX_SPEECH_BALLOON_H_
#include "common.h"
/* Contains a list of acceptable balloon types */
enum ESpeechBalloonType
{
ESpeechBalloonType_Talk,
ESpeechBalloonType_Thought,
ESpeechBalloonType_Yell,
ESpeechBalloonType_Whisper
};
/* Speech Balloon types */
struct X2D_SPEECH_BALLOON
{
struct X2D_SPRITE sprBalloon;
struct X2D_FONT font;
enum ESpeechBalloonType eBalloonType;
};
#endif
X2D_GFX_SPEECH_BUBBLE.c
#include "X2D_GFX_SPEECH_BALLOON.h"
Your issue is the order in which files are included, specifically in X2D_GFX_Sprite.c. If you run just the preprocessor on that file (in Linux you can use cpp or gcc -E, I don't know how in Windows) and scroll down to the very end, you'll find that the X2D_SPRITE struct is being declared after it's used:
struct X2D_SPEECH_BALLOON
{
struct X2D_SPRITE sprBalloon;
struct X2D_FONT font;
enum ESpeechBalloonType eBalloonType;
};
# 11 "common.h" 2
# 7 "X2D_GFX_Sprite.h" 2
struct X2D_SPRITE
{
float x;
float y;
unsigned int width;
unsigned int height;
int blnShow;
float vx, vy;
float angle;
int varsi[10];
};
Two easiest ways to fix it would be to either not use common.h or move #include "common.h" after the struct declaration in X2D_GFX_Sprite.h.
This happens because X2D_GFX_Sprite.c includes X2D_GFX_Sprite.h, which includes common.h, which includes the other .h files. The preprocessor first copies in X2D_GFX_Sprite.h. When it finds #include "common.h", it begins copying that file. The first three includes are copied in. When it gets back to X2D_GFX_Sprite.h, it'll copy it in, but the header guards will get rid of everything in it. Next, it copies in X2D_GFX_Font.h and X2D_GFX_Speech_Balloon.h, which includes the X2D_SPEECH_BALLOON struct, in that order. Only then does it finally add in the rest of X2D_GFX_Sprite.h, including the X2D_SPRITE struct. This results in the two structs not being copied in the correct order.

Resources