In my project I have these 2 files. When I try to compile it a get some peculiar warnings that I cannot solve, though my program runs fine. I use the -Wall and -Wextra arguments at compile.
//File: DataStructures.h
typedef struct EntryListPacketStruct EntryListPacket;
typedef struct IndexesPacketStruct IndexesPacket;
typedef struct MatchingQueriesResultStruct MatchingQueriesResult;
typedef struct DataPacketStruct* DataPacketPtr;
extern DataPacketPtr Packet;
EntryListPacket* allocateEntryListPacket(void);
void initializeDataPacket(DataPacketPtr);
void freeDataPacket(DataPacketPtr);
void initializeEntryListPacket(EntryListPacket*);
void freeEntryListsPacket(EntryListPacket*);
I include the DataStructures.h in the following file:
//File: DataStructures.c
struct EntryListPacketStruct {
EntryList* exactTypeEntryList;
EntryList** editDistEntryLists;
EntryList** hammingDistEntryLists;
};
struct DataPacketStruct {
struct EntryListPacket* entryLists;
struct IndexesPacket* indexes;
dllistptr matchingQResultList;
};
EntryListPacket* allocateEntryListPacket(void){
EntryListPacket* temp=malloc(sizeof(EntryListPacket));
return temp;
}
void initializeDataPacket(DataPacketPtr packet){
DataPacketPtr temp;
temp=malloc(sizeof(struct DataPacketStruct));
initializeEntryListPacket(temp->entryLists);
initializeIndexesPacket(temp->indexes);
packet=temp;
}
void freeDataPacket(DataPacketPtr packet){
freeEntryListsPacket(packet->entryLists);
freeIndexesPacket(packet->indexes);
free(packet);
}
void initializeEntryListPacket(EntryListPacket* packet) {
packet->exactTypeEntryList = NULL;
packet->editDistEntryLists = malloc(sizeof (EntryList)*22);
int i;
for (i = 0; i < 22; i++) {
packet->editDistEntryLists[i] = NULL;
}
packet->hammingDistEntryLists = malloc(sizeof (EntryList)*27);
for (i = 0; i < 27; i++) {
packet->hammingDistEntryLists[i] = NULL;
}
}
void freeEntryListsPacket(EntryListPacket* packet){
if(packet->exactTypeEntryList!=NULL)
DestroyEntryList(packet->exactTypeEntryList);
free(packet->exactTypeEntryList);
int i;
for(i=0;i<22;i++){
if(packet->editDistEntryLists[i]!=NULL){
printf("%d\n",i);
DestroyEntryList(packet->editDistEntryLists[i]);
}
free(packet->editDistEntryLists[i]);
}
free(packet->editDistEntryLists);
for(i=0;i<27;i++){
if(packet->hammingDistEntryLists[i]!=NULL){
printf("%d\n",i);
DestroyEntryList(packet->hammingDistEntryLists[i]);
}
free(packet->hammingDistEntryLists[i]);
}
free(packet->hammingDistEntryLists);
free(packet);
}
//File:main.c
EntryListPacket *temp;
temp=allocateEntryListPacket();
initializeEntryListPacket(temp);
freeEntryListsPacket(temp);
And I get the following Warnings:
DataStructures.c: In function ‘initializeDataPacket’:
DataStructures.c:48:6: warning: passing argument 1 of ‘initializeEntryListPacket’ from incompatible pointer type [enabled by default]
initializeEntryListPacket(temp->entryLists);
^
In file included from DataStructures.c:6:0:
DataStructures.h:27:10: note: expected ‘struct EntryListPacket *’ but argument is of type ‘struct EntryListPacket *’
void initializeEntryListPacket(EntryListPacket*);
^
DataStructures.c:50:6: warning: passing argument 1 of ‘initializeIndexesPacket’ from incompatible pointer type [enabled by default]
initializeIndexesPacket(temp->indexes);
^
In file included from DataStructures.c:6:0:
DataStructures.h:30:10: note: expected ‘struct IndexesPacket *’ but argument is of type ‘struct IndexesPacket *’
void initializeIndexesPacket(IndexesPacket*);
^
DataStructures.c:43:42: warning: parameter ‘packet’ set but not used [-Wunused-but-set-parameter]
void initializeDataPacket(DataPacketPtr packet){
^
DataStructures.c: In function ‘freeDataPacket’:
DataStructures.c:57:6: warning: passing argument 1 of ‘freeEntryListsPacket’ from incompatible pointer type [enabled by default]
freeEntryListsPacket(packet->entryLists);
^
In file included from DataStructures.c:6:0:
DataStructures.h:28:10: note: expected ‘struct EntryListPacket *’ but argument is of type ‘struct EntryListPacket *’
void freeEntryListsPacket(EntryListPacket*);
^
DataStructures.c:58:6: warning: passing argument 1 of ‘freeIndexesPacket’ from incompatible pointer type [enabled by default]
freeIndexesPacket(packet->indexes);
^
In file included from DataStructures.c:6:0:
DataStructures.h:31:10: note: expected ‘struct IndexesPacket *’ but argument is of type ‘struct IndexesPacket *’
void freeIndexesPacket(IndexesPacket*);
I cannot figure out what I am doing wrong or if the compiler is stuck since this for example: DataStructures.h:28:10: note: expected ‘struct EntryListPacket *’ but argument is of type ‘struct EntryListPacket *’
doesn't seem reasonable to me.
Thx in advance!
Your struct tags include a Struct suffix, but you omitted it when you declared:
struct DataPacketStruct {
struct EntryListPacket* entryLists;
struct IndexesPacket* indexes;
dllistptr matchingQResultList;
};
It should be:
struct DataPacketStruct {
struct EntryListPacketStruct* entryLists;
struct IndexesPacketStruct* indexes;
dllistptr matchingQResultList;
};
Or just:
struct DataPacketStruct {
EntryListPacket* entryLists;
IndexesPacket* indexes;
dllistptr matchingQResultList;
};
Also, your initializeDataPacket function is leaking the memory. Assigning temp to packet doesn't return the value since packet is passed by value, not by reference.
In DataStructures.h, try replacing this:
struct DataPacketStruct {
struct EntryListPacket* entryLists;
...
With this:
struct DataPacketStruct {
EntryListPacket* entryLists;
...
Or this:
struct DataPacketStruct {
struct EntryListPacketStruct* entryLists;
...
And similarly for struct IndexesPacket* indexes;. The compiler warning comes from missing the typedef symbol up with the struct symbol itself.
Related
I'm facing two errors when trying to assign a value to the components of a struct and later when passing a pointer of struct to a function.
I have a user-defined data type: my_node defined in a header file as follows:
enum n_type
{
N_COMMAND,
N_PIPE,
N_REDIRECT,
N_SUBSHELL,
N_SEQUENCE,
N_DETACH
};
struct my_node;
typedef struct my_node node_t;
struct my_node
{
enum n_type type;
union {
struct {
char *program;
char **argv;
size_t argc;
} command;
struct {
node_t **parts; // array
size_t n_parts;
} pipe;
struct {
... etc
}
and I have a function that takes a pointer to a my_node variable:
void run_command(struct my_node *a_node);
In myprogram.c, I try to make a new node, populate its components, define a pointer to its address then pass the pointer to the function above like this:
// first I get input as a string:
fgets(str, 100, stdin);
// create the new node
struct my_node
{
enum n_type type;
union
{
struct {
char *program;
char **argv;
size_t argc;
} command;
};
} node;
// assign values to its components (values are just for testing)
node.type = N_COMMAND;
node.command.program = &str;
node.command.argv = &node.command.program;
node.command.argc = 3;
// define a pointer to the node
struct my_node *ptr;
ptr = &node;
//pass the pointer to run command to execute it
run_command(ptr);
When I try to compile, I get those weird errors:
gcc ./shell.c -o shelli
./shell.c: In function ‘main’:
./shell.c:37:23: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
node.command.program = &str;
^
./shell.c:47:14: warning: **passing argument 1 of ‘run_command’ from incompatible pointer type** [-Wincompatible-pointer-types]
run_command(ptr);
^~~
In file included from ./shell.c:2:0:
./shell.h:21:6: note: **expected ‘struct tree_node *’ but argument is of type ‘struct tree_node *’**
void run_command(struct tree_node *n);
^~~~~~~~~~~
How come that the provided and requested argument types are the same but still there's an error?
What is the type of str? My guess is that it's a char* since you used it as a parameter to fgets, and the compiler didn't complain. If that is the case, then
node.command.program = &str;
doesn't compile since node.comand.program has type char*, but the type of &str is char**. So, the solution is to remove the &, ie.
node.command.program = str;
The compile messages indicate a struct tree_node type, but that type isn't defined in your question. I'll assume it is similar to your struct node definition. With this assumption, the run_command(ptr) is a problem since you redefined what a struct node is in your source file. The redefinition is not compatible with the original definition in the header file. You should define a struct only once in a header file, and then include that header file in any source file that uses that struct.
I'm try to use my struct peer_struct.h in multiple files. It is declared in main.c and I pass the struct trough reference.
The compiler gives me warings for the functions and I really don't understand why.
compiler Warnings:
In file included from first_use.c:1:0:
second_use.h:1:51: warning: ‘struct Peer_Information’ declared inside parameter list will not be visible outside of this definition or declaration
void second_use(char *message, int number, struct Peer_Information *peer);
^~~~~~~~~~~~~~~~
first_use.c: In function ‘first_use’:
first_use.c:6:23: warning: passing argument 3 of ‘second_use’ from incompatible pointer type [-Wincompatible-pointer-types]
second_use(me, 5, peer);
^~~~
In file included from first_use.c:1:0:
second_use.h:1:6: note: expected ‘struct Peer_Information *’ but argument is of type ‘struct Peer_Information *’
void second_use(char *message, int number, struct Peer_Information *peer);
^~~~~~~~~~
In file included from main.c:4:0:
first_use.h:1:23: warning: ‘struct Peer_Information’ declared inside parameter list will not be visible outside of this definition or declaration
void first_use(struct Peer_Information *peer);
^~~~~~~~~~~~~~~~
main.c: In function ‘main’:
main.c:28:15: warning: passing argument 1 of ‘first_use’ from incompatible pointer type [-Wincompatible-pointer-types]
first_use(&peer);
^
In file included from main.c:4:0:
first_use.h:1:6: note: expected ‘struct Peer_Information *’ but argument is of type ‘struct Peer_Information *’
void first_use(struct Peer_Information *peer);
peer_struct.h
struct Peer_Information {
char ownIP[16];
char ownPort[6];
unsigned int ownID;
char successor_IP[16];
char successor_Port[6];
unsigned int successor_ID;
char predecessor_IP[16];
char predecessor_Port[6];
unsigned int predecessor_ID;
} Peer_Information;
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "first_use.h"
#include "peer_struct.h"
void init_peer(char *argv[], struct Peer_Information *peer){
//Fills struct up, not import for question
}
int main(int argc, char *argv[]) {
if (argc != 10) {
printf("Nicht genügend Parameter \n");
return -1;
}
struct Peer_Information peer;
init_peer(argv, &peer);
first_use(&peer);
return 0;
}
first_use.c
#include "second_use.h"
#include "peer_struct.h"
void first_use(struct Peer_Information *peer) {
char me[] = "Hello";
second_use(me, 5, peer);
}
first_use.h
void first_use(struct Peer_Information *peer);
second_use.c
#include <stdio.h>
#include <stdlib.h>
#include "peer_struct.h"
void second_use(char *message, int number, struct Peer_Information *peer) {
printf("%d", peer->ownID);
}
second_use.h
void second_use(char *message, int number, struct Peer_Information *peer);
The very first warning tells it all. When you include first_use.h in main.c, the only thing which gets included is the prototype for the function
void first_use(struct Peer_Information *peer);
The type Peer_Information is not yet defined, so compiler generates a type with the same name which is local to this function. Than nothing works as it should, because you end up calling the function with the different (from compiler's standpoint) type which just happen to have the same name.
To fix it, you should make it a habit to include all header files required for the header files. In your case, include definition of the type as well and make your first_use.h to be like following:
#include "peer_struct.h"
void first_use(struct Peer_Information *peer);
In addition to that, your include file misses so-called include guard. You can get more details about those here: What exactly do C include guards do?
I am having problems passing a pointer to a pointer(struct) through a nested function to have memory allocated or reallocated for it. I understand that when passing to a function it is passed by value, and thus only can be edited locally, but am unclear syntactically how to pass it. Important code snippets below:
struct courseData{
char name[25];
int id;
};
void menuSwitch(int* courseNum, struct courseData** course);
void addCourse(int* courseNum, struct courseData** course);
int main(){
struct courseData* course = NULL;
int courseNum = 0;
menuSwitch(courseNum, &course); //Edited from original post.
return 0;
}
void menuSwitch(int* courseNum, struct courseData** course){
addCourse(&courseNum, course)
}
menuSwitch is actually a case switch, which calls function addCourse when the menu item is selected.
void addCourse(int* courseNum, struct courseData** course){
if(*courseNum == 0)
*course = (struct courseData*) malloc(sizeof(struct courseData));
else
*course = (struct courseData*) realloc(*course, (*courseNum + 1)*sizeof(struct courseData));
*courseNum = *courseNum + 1; //Increments course count by 1
------code continues------
}
After correcting original problem, compiling results in the following errors/warnings from gcc
main.c: In function ‘main’:
main.c:27:3: warning: passing argument 2 of ‘menuSwitch’ from incompatible pointer type [enabled by default]
header.h:24:6: note: expected ‘struct courseData *’ but argument is of type ‘struct courseData **’
func.c:60:6: error: conflicting types for ‘menuSwitch’
header.h:24:6: note: previous declaration of ‘menuSwitch’ was here
func.c: In function ‘menuSwitch’:
func.c:64:3: warning: passing argument 2 of ‘addCourse’ from incompatible pointer type [enabled by default]
header.h:26:6: note: expected ‘struct courseData *’ but argument is of type ‘struct courseData **’
Thank you for your help, and pardon if this is inappropriate use of the edit ability.
Everything is fine except one line. In void menuSwitch(int* courseNum, struct courseData** course) change
addCourse(&courseNum, course)
to
addCourse(courseNum, course);
You were doing fine until you got to menuSwitch. That function receives courseNum, which is a pointer to int. It should then pass that same pointer addCourse just as it does with course. However, you pass the address of courseNum instead. So instead of passing an int * you're passing the address of a pointer to int *, or an int **. The call to addCourse should simply be this:
addCourse(courseNum, course);
I am attempting to write a simple linked list just for practice and to jog my memory a little bit, but I have ran into trouble. I am pretty inexperienced in C, and I don't understand why this isn't working. I am trying to define a Node and a LinkedList struct, but every time I try to compile I get an error saying Node is an unknown type. I'm sure I am missing something, but I can't figure this out. Thanks all!
This is my ll.h file
1 #ifndef ll_h
2 #define ll_h
3
4 #include <stdio.h>
5
6 typedef struct {
7 void *data;
8 Node *next;
9 Node *prev;
10 } Node;
11
12
13 typedef struct {
14 Node *first;
15 Node *last;
16 int size;
17 } LinkedList;
18
19
20 void *getData(LinkedList list, int index);
21 int getSize(LinkedList list);
22 void *deleteNode(LinkedList, int index);
23 void add(LinkedList list, void *data);
24 void freeList(LinkedList list);
25
26 #endif
Errors I am receiveing
cc -Wall -g -c -o ll.o ll.c
In file included from ll.c:3:0:
ll.h:8:5: error: unknown type name ‘Node’
ll.h:9:5: error: unknown type name ‘Node’
ll.c: In function ‘getData’:
ll.c:8:18: error: expected expression before ‘LinkedList’
ll.c:12:7: warning: assignment from incompatible pointer type [enabled by default]
ll.c: In function ‘getSize’:
ll.c:21:12: error: expected expression before ‘LinkedList’
ll.c: In function ‘deleteNode’:
ll.c:26:18: error: expected expression before ‘LinkedList’
ll.c:32:7: warning: assignment from incompatible pointer type [enabled by default]
ll.c:37:12: error: request for member ‘next’ in something not a structure or union
ll.c:38:12: warning: assignment from incompatible pointer type [enabled by default]
ll.c:40:12: error: request for member ‘next’ in something not a structure or union
ll.c: In function ‘add’:
ll.c:52:16: warning: assignment from incompatible pointer type [enabled by default]
ll.c:54:21: warning: assignment from incompatible pointer type [enabled by default]
ll.c: In function ‘freeList’:
ll.c:61:18: error: expected expression before ‘LinkedList’
ll.c:62:18: warning: initialization from incompatible pointer type [enabled by default]
ll.c:65:7: warning: assignment from incompatible pointer type [enabled by default]
ll.c:67:7: warning: assignment from incompatible pointer type [enabled by default]
ll.c:62:11: warning: variable ‘next’ set but not used [-Wunused-but-set-variable]
ll.c:60:9: warning: unused variable ‘i’ [-Wunused-variable]
ll.c: In function ‘main’:
ll.c:85:6: error: ‘LinkedList’ has no member named ‘add’
ll.c:91:10: warning: dereferencing ‘void *’ pointer [enabled by default]
ll.c:91:10: error: void value not ignored as it ought to be
ll.c: In function ‘getSize’:
ll.c:22:1: warning: control reaches end of non-void function [-Wreturn-type]
make: *** [ll.o] Error 1
Use this:
typedef struct Node{
void *data;
struct Node *next; // note here
struct Node *prev;
} Node;
You either need forward declaration, or you need to drop the typedef. You can also use typedef with having the Node twice.
Forward declaration
typedef struct Node Node; // Necessary in C, harmless (but non-idiomatic) in C++
typedef struct {
void *data;
Node *next;
Node *prev;
} Node;
No typedef (Will only work in C++, not C)
struct Node {
void *data;
Node *next;
Node *prev;
};
Using typedef with tag
Works in C and C++, but non-idiomatic for C++.
typedef struct Node {
void *data;
struct Node *next;
struct Node *prev;
} Node;
Posting an Answer for the next reader brought here by Google searching:error: void value not ignored as it ought to be
Remember when trying to implement pseudo-code that function pointers get initialized with the name of the function without any parenthesis. Rookie mistake? Maybe, but I'm not exactly rookie (taught C/C++ Labs at university in mid 90s) and it got me. Had I typed it and not cut-n-pasted, I probably would have caught the error, as I know not to create that code...
Example with declarations supplied for completeness:
// Static menu manager
#define MAX_SELECTIONS 4
#define MAX_PROMPT_LEN 20
typedef struct _selection {
char prompt[MAX_PROMPT_LEN];
void(*function) ( void );
int fn_arg;
} SELECTION ;
typedef struct _menu {
int id;
int num_selections;
SELECTION selection[MAX_SELECTIONS];
} MENU;
enum _menu_ids { MAIN_MENU, DEPOSIT_MENU, WITHDRAWL_MENU, BALANCE_MENU };
enum _menu_keys { DEPOSIT, WITHDRAWL, BALANCE, CHECKING, SAVINGS };
Wrong:
// WRONG
static MENU menu[] = {
{ MAIN_MENU, 4,
{"Perform A Deposit", goto_menu(), DEPOSIT_MENU},
{"Perform a Withdrawl", goto_menu(), WITHDRAWL_MENU },
{"Get Balance", goto_menu(), BALANCE_MENU },
{"Hide Menu", menu_hide(), 0}
}
}
Correct:
// Correct
static MENU menu[] = {
{ MAIN_MENU, 4, {
{"Perform A Deposit", goto_menu, DEPOSIT_MENU},
{"Perform a Withdrawl", goto_menu, WITHDRAWL_MENU },
{"Get Balance", goto_menu, BALANCE_MENU },
{"Hide Menu", menu_hide, 0} }
}
}
Particularly observant readers might notice the additional braces required to initialize the struct's array's members were missing in the pseudo-code. The gcc compiler was kind enough to provide a useful error:MENU: improper number of initializers.
#include <stdio.h>
typedef struct
{
int data;
struct node *next;
}node;
void print(node *head)
{
node *tmp = head;
while (tmp)
{
printf ("%d ", tmp->data);
tmp = tmp->next;
}
}
int main()
{
node arr[5] = {
{1, &arr[1]},
{2, &arr[2]},
{3, &arr[3]},
{4, &arr[4]},
{5, NULL}
};
print(arr);
return 0;
}
Why do i get these warnings while compiling with gcc -Wall ? (even without -Wall, gcc produces the same warnings)
list.c: In function ‘print’:
list.c:15:7: warning: assignment from incompatible pointer type [enabled by default]
list.c: In function ‘main’:
list.c:22:18: warning: initialization from incompatible pointer type [enabled by default]
list.c:22:18: warning: (near initialization for ‘arr[0].next’) [enabled by default]
list.c:23:18: warning: initialization from incompatible pointer type [enabled by default]
list.c:23:18: warning: (near initialization for ‘arr[1].next’) [enabled by default]
list.c:24:18: warning: initialization from incompatible pointer type [enabled by default]
list.c:24:18: warning: (near initialization for ‘arr[2].next’) [enabled by default]
list.c:25:18: warning: initialization from incompatible pointer type [enabled by default]
list.c:25:18: warning: (near initialization for ‘arr[3].next’) [enabled by default]
What #metalhead said was correct. Another probably better way to achieve the same result is
typedef struct _node
{
int data;
struct _node *next;
} node;
After this definition node (without underscore) can simply be used as a type name like e.g. int.
P.S. The underscore is just a standard convention, not a requirement. Any name could have been used in place of _node as long as you replace in both occurrences. However, in c this is a norm and sort of a coding convention that helps the devs to quickly understand _node refers to the node type actually.
You are trying to use struct node inside the definition of node so therefore the compiler doesn't know you mean them to be the same thing. Try forward declaring the struct first:
struct node;
struct node
{
int data;
struct node *next;
};