enum and struct definition - c

I have errors when compiling my project with codeblocks.
My problem comes from a enum definition, and from a struct definition.
They are bot defined in a header file, that worked since i was only using those enum and struct in the .c associated file. But when i include the .h file in another .c file, i get errors, here is some code;
maps.h
#include <stdlib.h>
#include <stdio.h>
enum Property { BACKGROUND, FOREGROUND, BLOCK, EVENT };
typedef struct {
char map_name[50];
int width;
int height;
char* map_struct;
}rpgMap;
char getTileProperty(rpgMap map, int x, int y, int property);
maps.c
#include "maps.h"
char getTileProperty(rpgMap map, int x, int y, int property){ // Works
char value = NULL;
value = map.map_struct[(((y*(map.width-1))+y+x) * 4 ) + property];
return value;
}
rpgMap loadMap(unsigned char* map){
rpgMap Map;
//....
//some code
//...
return Map;
}
// This works until i include maps.h in another .c file
So here's the stuff, when i include maps.h in eg. game.c or game.h i have this error;
error: nested redefinition of 'enum Property'
I don't get it !

You need to add header guards to your header files otherwise you will get multiple declarations.
For example, for your maps.h surround it with this:
#ifndef MAPS_H
#define MAPS_H
...
#endif

Any source file that includes your header file will declare a single instance variable with the possible enumerated values of { BACKGROUND, FOREGROUND, BLOCK, EVENT }. I'm not sure that this is your intention. In general it is not good practice to do so.
If you intended to declare a type of enumeration and allow instances to be created elsewhere, put this in your header file:
typedef enum { BACKGROUND, FOREGROUND, BLOCK, EVENT } Property_t;
And then in your source files, declare the enumeration like so:
static Property_t property = BACKGROUND;
If you intended to create a variable that can be accessed from multiple source files then do put this in your header file:
typedef enum { BACKGROUND, FOREGROUND, BLOCK, EVENT } Property_t;
extern Property_t property;
and in a single source file, declare the variable:
Property_t property = BACKGROUND;

Related

Including enums defined in header

I have been fiddling with enums for a while and wanted to try to use them in a project. The project structure is as follows:
// protocol.h
#ifndef PROTOCOL_H
#define PROTOCOL_H
enum C_C {P_NORTH = 0,
P_WEST = 1,
P_SOUTH = 2,
P_EAST = 3};
#endif
// other.h
#include "protocol.h"
struct cmd {
enum C_C code : 4;
};
void make_cmd(struct cmd*, enum C_C);
This file triggers the following errors:
field 'code' has incomplete type
'enum C_C' declared inside parameter list will not be visible outside of this definition or declaration
// other.c
#include "other.h"
void make_cmd(struct cmd* cmd, enum C_C code) {
cmd->code = code;
}
This throws the following errors:
conflicting types for 'make_cmd'
I have tried changing the enum to a type using typedef with no luck. This happens also with function definitions which rely on this type of parameters.
Will throw the following error:
type of formal parameter 2 is incomplete
Thanks for your help.
This only happens when using the defined enum in another header, either for structs or for functions prototypes.
I do believe there must be some issue with the compilation order. I have tested in Xilinx SDK and Vitis with the same result.
protocol.h holds all the definitions of the enums and the structures to be used throughout the project. I was hoping by just including this one in the other headers the definitions would be available to build the other.h and other.c on top of that one.
Update:
I have moved the definition of the structure inside the protocol.h and it lets me add a member using the enum without issues. I guess the problem is when importing protocol.h into another header and trying to use the enum there the compiler has all of the headers in the
This code compiles:
#include "other.h"
void make_cmd(struct cmd* cmd, enum C_C code) {
cmd->code = code;
}
int main(int argc, char *argv[])
{
struct cmd cmd;
make_cmd(&cmd, P_WEST);
}
If you #include "protocol.h" as well you'll get an error (type redefinition) because it is already included in other.h.

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.

Declaring an extern struct template in header file for global use in c files

My goal is to declare and define a single structure template in my header file. I then wish to use this template to declare and define individual structures in my c files.
This is a rough example of what I'm aiming for:
header file
#include <bool.h>
extern struct options
{
extern bool aflag;
extern bool cflag;
extern bool dflag;
} option1;
...
c file
#include "header.h"
struct options option1;
void function(void)
{
option1.aflag = true;
option1.cflag = true;
option1.dflag = true;
}
...
I want this to result in the structure option1 being globally visible. The global contents should be aflag = true, cflag = true, and dflag = true.
When I say global, I mean that the contents aflag = true, cflag = true, and dflag = true (defined in another c file) should now be usable in yet a second c file if I wish. The only reference being the header file with the structure.
However, as I expected, this example contains multiple errors. I have only recently learned the basics of structures and am unsure of how to achieve exactly what I'm looking for, so it would be helpful if someone could explain how this effect can be achieved, possibly with code examples.
Thank you.
When you declare a structure you define a type.
If you want a struct to be globally visible then you need tp define a variable not a type.
So you can do something like this in your foo.h header file:
struct foo {
int bar;
double baz;
};
extern struct foo globally_visible_foo_yay;
And then in the foo.c file you want:
#include "foo.h"
struct foo globally_visible_foo_yay = {.bar = 42, .baz = 42.0};
And in some other C file you can then use the globally visible struct by including the header.

Passing struct pointer as a parameter

I'm trying to compile this code in c. First of all i have this struct in a separate source file to use it like a "class" (dir.h)
//Structure
typedef struct s_dirobject {
int noteid;
char title[20];
int bytes;
char head[20];
bool is_dir;
struct s_dirobject* next;
} dirobject;
//Ops
void add_dirobject(dirobject* myDirobject,int num_dirobject, char title[20], int is_dir, int bytes, char head[20]);
int get_dirobject_noteid(dirobject* myDirobject,int num_note);
char* get_dirobject_title(dirobject* myDirobject,int num_note);
int get_dirobject_bytes(dirobject* myDirobject,int num_note);
char* get_dirobject_head(dirobject* myDirobject,int num_note);
bool isdir(dirobject* myDirobject, int num_note);
int get_dirobjects_len(dirobject* myDirobject);
void clear_dir(dirobject* myDirobject);
void init_dir(dirobject* myDirobject);
In second place i have the comms source to retrieve the contents of a directory from a remote file system, and fill the object (comms.c)
#include "notebook.h"
#include "dir.h"
dirobject* temporaldirobjects;
...
init_dir(temporaldirobjects);
while(cond) {
//Add retrieved item to the directory
add_dirobject(temporaldirobjects, index, title, is_dir, bytes, "");
}
//When done retrieving the contents from the source i do instantiate the notebook_window
notebook_init(source, path, temporaldirobjects);
Finally, my notebook window interface will look like this. (notebook.h)
#include "dir.h"
void notebook_init(char* source, char* path, dirobject* contents);
void notebook_deinit();
And its implementation (notebook.c)
void notebook_init(char* source, char* path, dirobject* contents) {
// Fill the vars
this_window_source=source;
this_window_path=path;
this_window_dirobjects=contents;
...
}
When i compile this code as is, i get the error saying that
../src/dir.h:13:16: error: redefinition of 'struct s_dirobject'
In file included from ../src/notebook.h:12:0,
from ../src/comms.c:25:
../src/dir.h:13:16: note: originally defined here
In file included from ../src/comms.c:27:0:
../src/dir.h:20:3: error: conflicting types for 'dirobject'
In file included from ../src/notebook.h:12:0,
from ../src/comms.c:25:
../src/dir.h:20:3: note: previous declaration of 'dirobject' was here
In file included from ../src/comms.c:27:0:
../src/dir.h:23:6: error: conflicting types for 'add_dirobject'
In file included from ../src/notebook.h:12:0,
from ../src/comms.c:25:
../src/dir.h:23:6: note: previous declaration of 'add_dirobject' was here
...
since the comms library includes dir.h and notebook.h, and notebook.h does it too.
and if i remove the include in notebook.h i got this other error:
In file included from ../src/comms.c:25:0:
../src/notebook.h:14:46: error: unknown type name 'dirobject'
How can i acheive this? I would like to keep it as clean code as i can.
You included two headers in file comms.c
#include "notebook.h"
#include "dir.h"
header notebook.h in turn includes header dir.h
#include "dir.h"
void notebook_init(char* source, char* path, dirobject* contents);
void notebook_deinit();
As result the structure is defined twice in the same compilation unit. You have to provide that each headers would be included only once in each compilation unit. To do this you have to supply header's quards. For example
#ifndef DIR_H
#define DIR_H
//Structure
typedef struct s_dirobject {
int noteid;
char title[20];
int bytes;
char head[20];
bool is_dir;
struct s_dirobject* next;
} dirobject;
//...
#endif
Or if the compiler supports #pragme once then you could use it.
Usually, multiple declarations are fine in c but multiple definition is not. In your code, you are including dir.h multiple times which is causing the redefinition of struct s_dirobject. Read something about "Header guard" or "Include Guard". here. Hope this solves your major issues with redefinitions.

How to use a defined struct from another source file?

I am using Linux as my programming platform and C language as my programming language.
My problem is, I define a structure in my main source file( main.c):
struct test_st
{
int state;
int status;
};
So I want this structure to use in my other source file(e.g. othersrc.). Is it possible to use this structure in another source file without putting this structure in a header?
You can define the struct in each source file, then declare the instance variable once as a global, and once as an extern:
// File1.c
struct test_st
{
int state;
int status;
};
struct test_st g_test;
// File2.c
struct test_st
{
int state;
int status;
};
extern struct test_st g_test;
The linker will then do the magic, both source file will point to the same variable.
However, duplicating a definition in multiple source files is a bad coding practice, because in case of changes you have to manually change each definition.
The easy solution is to put the definition in an header file, and then include it in all the source file that use the structure. To access the same instance of the struct across the source files, you can still use the extern method.
// Definition.h
struct test_st
{
int state;
int status;
};
// File1.c
#include "Definition.h"
struct test_st g_test;
// File2.c
#include "Definition.h"
extern struct test_st g_test;
You can use pointers to it in othersrc.c without including it:
othersrc.c:
struct foo
{
struct test_st *p;
};
but otherwise you need to somehow include the structure definition. A good way is to define it in main.h, and include that in both .c files.
main.h:
struct test_st
{
int state;
int status;
};
main.c:
#include "main.h"
othersrc.c:
#include "main.h"
Of course, you can probably find a better name than main.h
// use a header file. It's the right thing to do. Why not learn correctly?
//in a "defines.h" file:
//----------------------
typedef struct
{
int state;
int status;
} TEST_ST;
//in your main.cpp file:
//----------------------
#include "defines.h"
TEST_ST test_st;
test_st.state = 1;
test_st.status = 2;
//in your other.ccp file:
#include "defines.h"
extern TEST_ST test_st;
printf ("Struct == %d, %d\n", test_st.state, test_st.status);
Putting it in a header file is the normal, correct way to declare types shared between source files.
Barring that, you can treat main.c as a header file and include it in the other file, then only compile the other file. Or you can declare the same struct in both files and leave a note to yourself to change it in both places.
C supports separate compilation.
Put the structure declaration in a header file and #include "..." it in the source files.
It is perfectly reasonable to be inclusive with structs by leaving them in the source file instead. This is encapsulation. However if you're going to redefine struct multiple times in multiple source files then you might as well define the struct once in a header file instead and include that file as necessary.
Header file /* include this header file in both file1.c and file2.c
struct a {
};
struct b {
};
so header file included the declaration of both structures .
file 1.c
struct a xyz[10]; --> struct a defined here
to use struct b here in this file
extern struct b abc[20];
/* now can use in this file */
file2.c
struct b abc[20]; /* defined here */
to use struct a defined in file1.c
use extern struct a xyz[10]

Resources