Strange pointer warning while printing directory listing - c

I have the following code to print the directory listing in unix.
struct dirent *res;
struct DIR *dir;
scanf("%s",str);
dir=opendir(str);
if(dir==NULL)
{
perror("Invalid directory");
return 1;
}
res=(struct dirent *)readdir(dir);
while(res)
{
printf("%s\n",res->d_name);
res=(struct dirent *)readdir(dir);
}
When I compile the above code I get the following warning
ls.c:16:17: warning: passing argument 1 of ‘readdir’ from incompatible pointer type
[enabled by default]
/usr/include/dirent.h:164:23: note: expected ‘struct DIR *’ but argument is of type
‘struct DIR *’
ls.c:20:21: warning: passing argument 1 of ‘readdir’ from incompatible pointer type
[enabled by default]
/usr/include/dirent.h:164:23: note: expected ‘struct DIR *’ but argument is of type
‘struct DIR *’
What does GCC exactly mean when it says "Expected argument foo but argument is of type foo"?
I also tried using struct DIR dir instead of *dir and &dir instead of dir,but it results in following error
ls.c:7:12: error: storage size of ‘dir’ isn’t known
PS:The output of the code is perfectly OK.

DIR is a macro which generally expands to struct something, so you're declaring struct struct something *dir. Which is apparently a confusing thing to do (though, also apparently, fine by GCC), leading to a confusing error message. The solution is simply to declare DIR *dir, without the struct.

Ben has the correct solution to your problem, but this does look like a serious problem in how gcc reports this error.
First of all, it wasn't a macro issue. DIR is a typedef for struct __DIR (at least that's what it is here, and I get the same error message). There is no struct DIR except the one declared by struct DIR *dir; but gcc seems to be saying there is another type with that name.
This sample compilation unit demonstrates the problem more clearly:
struct foo {
int a,b,c;
};
typedef struct foo bar;
void do_bar(bar *);
void func(void)
{
int i = 0;
/* do_bar wants a bar *, which is a struct foo *, but we're giving it an
int * instead. What will gcc say? */
do_bar(&i);
}
gcc reports:
t.c: In function ‘func’:
t.c:15:7: warning: passing argument 1 of ‘do_bar’ from incompatible pointer type [enabled by default]
t.c:7:10: note: expected ‘struct bar *’ but argument is of type ‘int *’
but there is no struct bar in the code at all. It has taken the bar typedef and crammed the word struct in front of it for no reason.

Related

pointer confusion - error: passing argument 1 of ‘value’ from incompatible pointer type; note: expected ‘...’ but argument is of type ‘...'

EDIT: This was so obvious, I have no idea how I didn't notice. Thanks for your help, guys!
I am making a symbol table using binary tree in C, and I got stuck while defining the basic functions. I have never been able to fully grasp pointer operations, and these errors are making my head hurt and I have no idea how to fix them, although I'm sure that many of you will find my problem trivial.
I have a structure defined like this:
typedef struct SymTable {
symbol_t *rootNode;
} symTable_t;
An initialisation function like this:
void initTable(symTable_t *table) {
table->rootNode = NULL;
}
And in my main.c I call the function:
symTable_t *newTable = malloc(sizeof(symTable_t));
// check if malloc was successful
initTable(&newTable);
It throws these two errors when I try to translate:
main.c:12:12: error: passing argument 1 of ‘initTable’
from incompatible pointer type [-Werror=incompatible-pointer-types]
initTable(&newTable);
^
In file included from main.c:1:0:
sym_tab.c:18:7: note: expected ‘symTable_t * {aka struct SymTable *}’ but argument is of type ‘symTable_t ** {aka struct SymTable **}’
void initTable(symTable_t *table) {
When I define initTable() like _initTable(symTable_t table)_, it only throws more errors.
Thank you in advance.
You're passing a pointer to a pointer to a symTable_t instead of just a pointer to a symTable_t.
Remove the & in this line:
initTable(&newTable);
and the error will go away.

passing pointers to nested functions

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);

Peculiar warnings at C

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.

Incompatible types when assigning to type ‘typedef from type ‘uint8_t’

I am running across a problem with typedefs.
typedef char cool_array_t[ARRAY_SIZE];
cool_array_t* out;
// do stuff with out
cool_array_t test = *out;
The error I am getting is the following:
incompatible types when assigning to type ‘cool_array_t’ from type
‘char *’
I tried casting out to cool_array_t but it gives the following error:
error: cast specifies array type
You cannot assign to arrays. You need to use memcpy or a wrapping struct.
struct cool_array_t {
char data[ARRAY_SIZE];
};
struct cool_array_t* out;
// do stuff with out
struct cool_array_t test = *out;

Confused about compiler errors received using gcc

I'm trying to compile this assignment I'm doing and I'm running into errors I'm not sure how to fix. Esepcially for Here's my command line argument:
gcc HW3.c semaphore.o buffer.c -L. -lst -o test
The problem is that the semaphor.h file was given to us so there isn't anything inherently wrong in the class so it shouldn't be complaining there I don't think. I'm not sure how to reconcile the struct errors either. I'm not particularly proficient in C. Here's the error list:
In file included from buffer.c:11:
semaphore.h:4: error: expected specifier-qualifier-list before ‘st_cond_t’
In file included from buffer.h:2,
from buffer.c:12:
semaphore.h:4: error: expected specifier-qualifier-list before ‘st_cond_t’
semaphore.h:5: error: conflicting types for ‘semaphore’
semaphore.h:5: note: previous declaration of ‘semaphore’ was here
semaphore.h:7: error: conflicting types for ‘down’
semaphore.h:7: note: previous declaration of ‘down’ was here
semaphore.h:8: error: conflicting types for ‘up’
semaphore.h:8: note: previous declaration of ‘up’ was here
semaphore.h:9: error: conflicting types for ‘createSem’
semaphore.h:9: note: previous declaration of ‘createSem’ was here
buffer.c: In function ‘init_buffer’:
buffer.c:20: error: incompatible type for argument 1 of ‘createSem’
semaphore.h:9: note: expected ‘struct semaphore *’ but argument is of type ‘semaphore’
buffer.c:21: error: incompatible types when assigning to type ‘semaphore’ from type ‘void *’
buffer.c:23: error: incompatible type for argument 1 of ‘createSem’
semaphore.h:9: note: expected ‘struct semaphore *’ but argument is of type ‘semaphore’
buffer.c:24: error: incompatible types when assigning to type ‘semaphore’ from type ‘void *’
buffer.c: In function ‘c_deposit’:
buffer.c:38: error: incompatible type for argument 1 of ‘down’
semaphore.h:7: note: expected ‘struct semaphore *’ but argument is of type ‘semaphore’
buffer.c:41: error: incompatible type for argument 1 of ‘up’
semaphore.h:8: note: expected ‘struct semaphore *’ but argument is of type ‘semaphore’
buffer.c: In function ‘c_remove’:
buffer.c:46: error: incompatible type for argument 1 of ‘down’
semaphore.h:7: note: expected ‘struct semaphore *’ but argument is of type ‘semaphore’
buffer.c:49: error: incompatible type for argument 1 of ‘up’
semaphore.h:8: note: expected ‘struct semaphore *’ but argument is of type ‘semaphore’
buffer.c:
#include <stdio.h>
#include <stdlib.h>
#include "semaphore.h"
#include "buffer.h"
buffer *init_buffer(int size)
{
buffer *new_Buffer;
new_Buffer=malloc((sizeof(buffer)));
createSem(new_Buffer->emptyBuffer, size);
new_Buffer->emptyBuffer=malloc(sizeof(semaphore));
createSem(new_Buffer->fullBuffer, 0);
new_Buffer->fullBuffer=malloc(sizeof(semaphore));
new_Buffer->chars=malloc(sizeof(char)*size);
new_Buffer->size=size;
new_Buffer->nextIn=0;
new_Buffer->nextOut=0;
return new_Buffer;
}
void c_deposit(buffer *buffer, char c)
{
down(buffer->emptyBuffer);
buffer->chars[buffer->nextIn]=c;
buffer->nextIn=(buffer->nextIn+1)%buffer->size;
up(buffer->fullBuffer);
}
int c_remove(buffer *buffer)
{
int c;
down(buffer->fullBuffer);
c=buffer->chars[buffer->nextOut];
buffer->nextOut=(buffer->nextOut+1)%buffer->size;
up(buffer->emptyBuffer);
return c;
}
buffer.h:
#include <stdio.h>
#include "semaphore.h"
typedef struct{
semaphore emptyBuffer;
semaphore fullBuffer;
int nextIn;
int nextOut;
int size;
char *chars;
}buffer;
void c_deposit(buffer *buffer, char c);
int c_remove(buffer *buffer);
buffer *init_buffer(int size);
For good measure here's semaphore.h as well:
typedef struct
{
int value;
st_cond_t sem_queue;
} semaphore;
void down(semaphore *s);
void up(semaphore *s);
void createSem(semaphore *s, int value);
Seems like semaphore.h needs to do this:
#include <st.h>
Also, you are including semaphore.h twice which is confusing the compiler.
Try putting this in semaphore.h as well:
#pragma once
See: http://en.wikipedia.org/wiki/Pragma_once

Resources