I have two header files that refer to each other and that produce a compile error if I do not carefully put my includes on the right lines. Each of my header files matches with a srcs directory:
___include
|____matrixes.h
|____define.h
|____transformations.h
|____tuples.h
|____pixels.h
|____ppm.h
|____Myproject.h
|____error_handler.h
|____graphics.h
Basically, Myproject.h contains all #include I needed, while every other header files contain prototypes, typedefs, structs, #defines I needed for the respective srcs directory. But I guess I got something wrong.
My problem comes from pixels.h, graphics.h and (maybe) Myproject.h. Here are they:
#ifndef PIXELS_H
# define PIXELS_H
# include "Myproject.h"
typedef uint32_t t_pixel;
typedef unsigned char t_color;
//////////////////////////
//# include "graphics.h"
//////////////////////////
// pixels/conversions.c
t_tuple pixel_to_point(t_image image, int i, int j);
t_tuple point_to_pixel(t_image image, double x, double y);
// pixels/print.c
void print_pixel(t_pixel p, char *name);
// pixels/pixels.c
t_pixel pixel(t_color r, t_color g, t_color b, t_color a);
t_color get_a(t_pixel pixel);
t_color get_r(t_pixel pixel);
t_color get_g(t_pixel pixel);
t_color get_b(t_pixel pixel);
// pixels/ops.c
t_pixel add_pixel(t_pixel p, t_pixel q);
t_pixel sub_pixel(t_pixel p, t_pixel q);
t_pixel scal_pixel(float q, t_pixel p);
t_pixel mul_pixel(t_pixel p, t_pixel q);
#endif
#ifndef GRAPHICS_H
# define GRAPHICS_H
# include "Myproject.h"
typedef struct s_window{
void *mlx;
void *win;
} t_window;
typedef struct s_image {
void *mlx;
void *img;
char *addr;
int bits_per_pixel;
int line_length;
int endian;
t_tuple origin;
t_tuple extension;
} t_image;
typedef struct s_canvas{
t_window window;
t_image image;
} t_canvas;
// graphics/graphics.c
t_window *window(t_window *cvs);
t_image *image(t_image *img, void *mlx);
t_canvas *canvas(t_canvas *canvas);
void put_pixel(t_image img, int x, int y, t_pixel pixel);
// graphics/free.c
void free_window(t_window *window);
void free_image(t_image *image);
void free_canvas(t_canvas *canvas);
#endif
#ifndef MYPROJECT_H
# define MYPROJECT_H
# include <unistd.h>
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <limits.h>
# include <stdbool.h>
# include <mlx.h>
# include <math.h>
# include <fcntl.h>
# include <sys/stat.h>
# include "libft.h"
# include "define.h"
# include "tuples.h"
# include "matrixes.h"
# include "pixels.h"
# include "graphics.h"
# include "ppm.h"
# include "error_handler.h"
# include "transformations.h"
#endif
As such, it did not compile with following error:
In file included from srcs/pixels/conversions.c:13:
In file included from include/miniRT.h:30:
include/pixels.h:22:24: error: unknown type name 't_image'
t_tuple pixel_to_point(t_image image, int i, int j);
^
include/pixels.h:23:24: error: unknown type name 't_image'
t_tuple point_to_pixel(t_image image, double x, double y);
I understand the error because the pixel_to_point function takes a t_image as argument and in Myproject.h, graphics.h is included after pixels.h so it does not recognize the t_image type.
If I try to invert the graphics.h and pixels.h includes in Myproject.h, I just get the same error when a function from graphics.h needs the t_pixel type.
I can make it run by uncommenting the commented #include graphics.h in pixels.h (because it is AFTER the t_pixel typedef) but I feel it is an ugly method.
Is there a rule to follow to avoid these issues ?
Consider your project include files to form some sort of hierarchy.
Have pixel.h only include "tuples.h", etc. What is needed, not "Myproject.h".
Likewise for "graphics.h".
Other strategies exist.
IMO, typedef unsigned char t_color; should not exist in "pixels.h", but only in "color.h".
IOWs, I recommend that each object/function/constant/macro declared in a xyz.h begin with a xyz_ or the like. OP's current approach has names spaces all over the place defined in a given .h file. I see this as hard to follow and unnecessarily difficult to maintain.
I would also recommend to rename functions like add_pixel() to pixel_add() to lead with the key-prefix pixel.
Related
I'm new in c programming.
I'm playing with an exercise where I created a main program called main.c that includes two other modules: modulo1 and modulo2 with rispettives headers.
Modulo1 contains some data and functions while modulo2 calls data and functions defined modulo1.
I put the lists:
main.c
#include <stdio.h>
#include <stdlib.h>
#include "modulo1.h"
#include "modulo2.h"
vector v1;
vector v2;
vector sm;
int
main (int argc,
char *argv[])
{
create(& v1 ,1 ,2 );
create(& v2 ,3 ,2 );
sum(& sm, & v1, & v2);
report (& v1);
report (& v2);
report (& sm);
printf("\n-----------------\nDone !\n-----------------\n");
return EXIT_SUCCESS;
}
Where
modulo1.h
struct vector
{
int x;
int y;
};
typedef struct vector vector;
void create(vector *v, int x, int y);
void sum(vector *sum, vector *v1, vector *v2);
modulo1.c
#include "modulo1.h"
void create(vector *v, int x, int y)
{
v->x = x;
v->y = y;
}
void sum(vector *sum, vector *v1, vector *v2)
{
sum->x = v1->x + v2->x;
sum->y = v1->y + v2->y;
}
and then the second modulo2.h
//#include "modulo2.h"
void report(vector *v);
and the modulo2.c is
#include "modulo2.h"
#include <stdio.h>
void report(vector *v)
{
printf("\n------------------\n The vector is:\n x:=%d\n y:=%d\n------------------\n", v->x, v->y);
}
When I build all like this I get some errors similar to this:
....modulo2.h:2:13: error: unknown type name ‘vector’
while when I include in modula2.h the #include "modulo1.h" I get another groups of errors like this following:
.....modulo1.h:1:8: error: redefinition of ‘struct vector’
The makefile is very easy:
modula1_SOURCES = \
main.c \
modulo1.c \
modulo1.h \
modulo2.c \
modulo2.h
I cannot understand where is the error and where I'm wrong.
Someone can help me ?
I think there is something wrong at header / include files ?
Thank you
Marco
When I build all like this I get some errors similar to this:
....modulo2.h:2:13: error: unknown type name ‘vector’
Because modulo2.h uses identifiers declared in modulo1.h, it needs to include modulo1.h.
… when I include in modula2.h the #include "modulo1.h" I get another groups of errors like this following:
.....modulo1.h:1:8: error: redefinition of ‘struct vector’
Because main.c includes modulo1.h and includes modulo2.h and the latter also includes modulo1.h, we have modulo1.h included twice, and so there are multiple definitions.
A way to resolve this is to use what are called header guards. In modulo1.h, we can put these lines at the beginning and the end:
#if !defined modulo1_h
#define modulo1_h
…
#endif // #if !defined modulo1_h
This will cause the contents of modulo1.h between those lines to be compiled only once:
The first time modulo1.h is included, modulo1_h is not defined, so !defined modulo1_h is true, and everything in the file is compiled.
That includes defining modulo1_h (with an empty replacement list).
The second time modulo1.h is included, modulo1_h is already defined, so !defined modulo1_h is false, and the rest of the file is not compiled.
This way, each file, whether it is main.c, modulo2.h, or another file can include modulo1.h if it needs any identifiers from that header, and it does not have to be concerned with whether anything has included it previously. If it has been included previously, there will be no multiple definitions. If it has not been included previously, its definitions (and declarations) will be applied.
I have a C project and I really don't get how to manage .c and .h.
I've been using a method for years but now I have to create codes without any warnings, so I need to change the way I do it.
Here is how I'm doing it:
Each .c have a .h with the same name. Even main.c has a main.h.
In each .c, I include the matching .h, so I have only one include per .c.
In main.h, I include all the libraries I need, like stdio stdlib and so on. I also declare my enumerations and structures there.
Finally, in every other .h, I include the main.h which contains the structures, enums and libraries.
I understand that by doing that, I call main.h a lot of time, but I use the #ifndef and #define in every .h.
Also, I each .h contains the prototypes of the functions in their corresponding .c
How should I manage .c and .h?
I forgot to mention that the problem is that I get a warning for every single function: "implicit declaration of function"
Here is an example with four files :
main.c :
#include "main.h"
int main()
{
// code
}
int save(Player players[2], int currentPlayer)
{
// code
}
int load(Player players[2], int* currentPlayer)
{
// code
}
main.h :
#ifndef MAIN_H
#define MAIN_H
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <string.h>
#include <math.h>
typedef enum Direction Direction;
typedef enum Orientation Orientation;
typedef enum ShipType ShipType;
typedef enum CaseType CaseType;
typedef enum Status Status;
typedef enum PlayerType PlayerType;
enum Direction
{
Nord=0, Est=1, Sud=2, Ouest=3
};
enum Orientation
{
None=0, Horizontal=1, Vertical=2
};
enum ShipType
{
SousMarin=1, Destroyer=2, Croiseur=3, Cuirasse=4
};
enum CaseType
{
Undiscovered=0, Empty=1, Hit=2, Detected=3, Discovered=5
};
enum Status
{
Undamaged=0, Damaged=1, Drowned=2
};
enum PlayerType
{
Human=0, Computer=1
};
typedef struct Map Map;
typedef struct Ship Ship;
typedef struct Player Player;
struct Map
{
int width, height;
int* cases;
};
struct Ship
{
int x, y, length, firstShoot, color;
int hasBeenDiscovered;
Orientation orientation;
ShipType type;
Status status;
};
struct Player
{
int totalShips;
int activeShips;
Map map[2];
char lastMoves[5][128];
Ship* ships;
PlayerType type;
int shipcolor[4];
int shipNumber[4];
int color;
};
int save(Player players[2], int currentPlayer);
int load(Player players[2], int* currentPlayer);
#endif // MAIN_H
IA.c :
#include "IA.h"
int IA(Player* IA, Player* enemy)
{
// code
}
// And all my other functions
IA.h :
#ifndef IA_H
#define IA_H
#include "main.h"
int IA(Player* IA, Player* enemy);
void endIATurn(Player* IA);
int enemyShipDiscovered(Map map, int* x, int* y, int SousMarinSpecific);
Ship* bestFriendlyActiveShip(Ship* ships, int totalShips, int SousMarinSpecific);
int friendlyShipDiscovered(Ship** ship, Ship* ships, Map map, int totalShips, int SousMarinSpecific);
int hitShipButNotDrowned(Player* IA, Player enemy, int totalShips, int* x, int* y);
int hasAtLeastOneMoveableShip(Player player);
int hasUndiscoveredCases(Player player);
void getUndiscoveredCoordoonnees(Map map, int* x, int* y);
int findNextCaseToShootAt(Map map, Ship ship, int* a, int* b);
#endif // IA_H
All my other .h are like IA.h
For foo.h and foo.c:
Use foo.h to tell other source files about things that foo.c provides. So foo.h will declare functions that are (a) defined in foo.c and (b) called from other source files. It will also declare any types or other things that those functions need or that other source files need in able to be able to use the functions.
In foo.h, only use #include to include header files that foo.h itself needs.
In foo.c, use #include "foo.h". This has two purposes: (1) It declares things that foo.c may need, without having to duplicate those declarations in foo.c. (2) It ensures that foo.c is using the same declarations that other source files see when they include foo.h, so any conflicts between declarations in foo.h and definitions in foo.c will produce compiler warnings or error messages.
If foo.c needs any headers that foo.h, include them in foo.c, not foo.h. Similarly, if foo.c has any functions that it uses for itself but does not expect other source files to use, declare them only in foo.c. Keep things that are just for foo.c inside foo.c. Use foo.h only for exporting things to other source files.
If there are any types or other declarations used by your program generally:
Put them in a suitably named file (e.g., bar.h for types involving some bar concept) and include it. Largely, you can treat bar.h as a pair bar.h and bar.c described above except that bar.cis empty.
Generally, there is no reason to make a main.h. Usually, main.c uses things that other source files provide and does not provide things for other sources to use (except that main is called by the C run-time start-up code).
I suggest the following:
Divide your functions in different .c files as you already do. For every .c create a .h
In every .h insert its include guard:
Within the include guard, start by including the .h of the libraries you need to declare your functions or to define structs, e.g. #include <stdlib.h> if you use size_t parameters.
Within the include guard, insert the structs, enums, ... you need exported
Within the include guard, insert the function declarations.
In every .c start by including its corresponding .h, then include other libraries needed to implement your functions, then put in the definitions.
Don't make a main.h or common.h, unless you have extremely good reasons for it (I know this will be commented against, but everyone has its style).
In main.c include what you need. You'll be including much less than you think.
I'm having trouble using a special type I made in two header files. One header files defines the type, the other one uses it in an extern variable, and a function.
"newtype.h"
typedef struct {
double i, s;
} newtype_t;
newtype_t this(){}
newtype_t that(){}
Now I have another header with a variable and function:
"newfuncs.h"
extern newtype_t c;
newtype_t divide(double d, double e);
I'm getting:
unknown type name 'newtype_t' //inside of "newfuncs.h"
This new header "newfuncs.h" is an addition to already working code that utilizes the new type and functions from "newtype.h".
I'm using this newtype_t inside of newfuncs.h.
I tried to #include "newtype.h" but I get a multitude of errors involving "conflicting types" in my .c files.
If a header use a type declared in another header, it should include it.
To prevent multiple declaration problem, you should add a guard in your header files:
// file newtype.h
#ifndef NEWTYPE_H // the guard
#define NEWTYPE_H
// all header stuff goes here
typedef int my_type;
#endif // end of guard
By doing this, each type or function will only be defined once. Each guard macro should be unique, you can use the file name to choose its name.
Some compiler (like cl) have a special comment to prevent multiple inclusion: #pragma once
did you included the header files in the right order?
I just tested it and it works
test.c
#include "newtype.h"
#include "newfuncs.h"
#include <stdio.h>
int main(){
double d = 4.0;
double e = 2.0;
c = divide(d, e);
printf("HELLO WORLD\n");
printf("%lf", c.i);
printf("%lf", c.s);
return 0;
}
newtype_t divide(double d, double e){
newtype_t x;
x.i = d;
x.s = e;
return x;
}
newtype.h
#ifndef NEWTYPE_H
#define NEWTYPE_H
typedef struct {
double i, s;
} newtype_t;
#endif
newfuncs.h
#ifndef NEWFUNCS_H
#define NEWFUNCS_H
newtype_t c;
newtype_t divide(double d, double e);
#endif
but even without the define it works for me (gcc 5.3.1).
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.
I have this include file (memory .h)
#ifndef MEMORY_H
#define MEMORY_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct mmemory {
int* cells;
int* current_cell;
int cells_number;
} memory;
void memory_init(memory* mymemory, int size);
void step_left(memory* mymemory, int steps);
void step_right(memory* mymemory, int steps);
void cell_inc(memory* mymemory, int quantity);
void print_cell(memory* mymemory);
void get_char(memory* mymemory);
#ifdef __cplusplus
}
#endif
#endif /* MEMORY_H */
And this implementation file (memory.c)
#include <stdlib.h>
#include "memory.h"
void
memory_init (memory* mymemory, int size)
{
mymemory->cells = (int*) malloc (sizeof (int) * size);
mymemory->cells_number = size;
mymemory->current_cell = (int*) ((mymemory->cells_number / 2) * sizeof (int));
}
... //other function definitions follow
When I try to compile memory.c I get this error for each and every function definition
src/memory.c:5: error: expected ')' before '*' token
where line 5 is the function definition for memory_init()
Can someone please tell me why I'm getting this error?
Because the system memory.h is shadowing your memory.h, causing the #include to succeed without declaring your types. Several possible fixes:
Rename your file -- probably for the best in any case, to reduce potential confusion.
Include your file via a prefix subdirectory (e.g., #include <myproj/memory.h>).
Move your file into the same directory as the source file, allowing the #include precedence rules for filenames wrapped in " to take effect.
Ensure that your C pre-processor include path options place your project header path prior to the system header paths.
This answer is really late, but I encountered a similar problem.
I think your problem is related to a typo in your .h file where you declare a struct mmemory. If you remove that extra 'm' it should work.
In your code you have defined like this for memory.h
#ifndef MEMORY_H
#define MEMORY_H
...
...
#endif
In case any of your other files which you use in your project is having the same #define i.e MEMORY_H then you can get this error.
Solution:
#ifndef XYZ_MEMORY_H
#define XYZ_MEMORY_H
...
...
#endif