Expected identifier error in C - c

For some reason I am getting the error:
expected identifier or '(' before 'wordlist'
in my header file (as well as the corresponding function definitions) for the two functions returning wordlist pointers.
With the following code:
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
typedef struct word{
char *string;
struct word* next;
}word;
typedef struct wordlist{
word *head;
word *tail;
}wordlist;
*wordlist populateList(FILE *file);
*wordlist encrypt(wordlist *wl, int rotation);
void toFile(wordlist *wl, char *outputFileName);
#endif
Can anyone tell me why this might be?

This is because when you declare a pointer, the asterisk must follow the type name, not precede it:
wordlist * populateList(FILE *file);
// ^
// |
// Here

If in populateList and encrypt you want to return a pointer to wordlist, the correct syntax is wordlist *, not *wordlist (it's exactly as it is everywhere else).

If you want to define or declare a variable you specify the type of the variable followed by the variable name. So if you want a variable of type wordlist you would use:
wordlist myVariable;
If you want to specify a variable to be a pointer to a variable type, you prefix the variable name with an asterisk so if you want a variable that is a pointer to a variable of type wordlist you would use:
wordlist *myVariable;
The reason why most experienced C programmers put the asterisk with the variable name is because of something like the following:
wordlist myVariable, *pVariable1, myVariable2, *pVariable2;
The above will create four variables. myVariable is of type wordlist. myVariable2 is of type wordlist. pVariable1 and pVariable2 are of type pointer to wordlist.
So the asterisk acts as a kind of adjective or qualifier or modifier for the variable name declaration indicating that the variable is not of the type specified but is instead a pointer to the type specified.
The combined variable definition is the same as the following four lines of definitions.
wordlist myVariable; // declares a variable of type wordlist
wordlist *pVariable1; // declares a pointer to a variable of type wordlist
wordlist myVariable2; // declares a variable of type wordlist
wordlist *pVariable2; // declares a pointer to a variable of type wordlist
Function definitions/declarations work similarly.
wordlist *myFunc (void) {
wordlist *myNew = malloc (sizeof(wordlist));
if (myNew) {
// set up myNew stuff
}
return myNew;
}
Edit: function pointers
You can also specify a variable that contains a function pointer. For instance for myFunc() above you might specify something like the following. Notice that I am using parenthesis to enforce a specific order of evaluation. What this says is that pFunc is a pointer to a function that does not accept arguments (void argument list) and which returns a pointer to a wordlist variable. There are rules about operator and modifier precedence in C however as expressions become more complicated, it is usually better to enforce an evaluation order using parenthesis. See Programs as Data: Function Pointers
wordlist *((*pFunc) (void)) = myFunc; // pointer to a function that returns a pointer to a wordlist

Related

How to user define array of function pointers which have same prototype as main function?

I have an assignment to typedef function pointers which can point to main function. I tried something like this but I'm not sure if it's viable.
typedef mainPtr(*f[])(int, char**);
The thing that bothers me is that array size is not defined. How would you do this?
The type of main (in the form you want) is int main(int, char **).
A pointer to that is int (*main)(int, char **).
An array of those is int (*main[])(int, char **).
A typedef of that is typedef int (*mainPtr[])(int, char **);.
Whether you need a size for the array depends on how you will use the type. If you define and initialize an object of this type, its array size will be completed by counting the initializers. For example:
mainPtr p = { main, NULL };
will create an array with two elements.
In other uses, such as declaring a function parameter with this type, you may not need the array to be complete. An array function parameter is automatically adjusted to be a pointer, so the size is discarded anyway. However, if you wish, you could include the size in the typedef.
The syntax is easier if you typedef function itself:
typedef int mainfunc(int, char **);
Then you can use the "normal" pointer syntax:
/* definition of the function pointer*/
mainfunc *mainptr;
/* definitions of the function pointer arrays*/
mainfunc *mainptrarray[5];
mainfunc *mainptrarray1[] = {foo, bar, NULL};

extern struct declaration in C

I'm fairly new to C, hence could someone please help me understand the below struct declaration?
extern struct server_module* module_open (const char* module_path);
Per my understanding, module_open is pointer to the struct server_module, however, didn't understand the last part of the statement i.e. (const char* module_path)
extern struct server_module* module_open (const char* module_path); declares module_open to be a function taking a parameter named module_path of type const char * and returning a struct server-module *.
module_open is a function which returns pointer to struct server_module
and const char* module_path is input argument type. Means function takes character string as an input
extern keyword is used to tell compiler that symbol is exist in different file

What is wrong with this header file?

I'm fairly new to C and am starting to learn header files. Whilst using my header I'm getting an error saying invalid type argument of '->' (have struct dirent). I don't understand what this means, I read here that the second argument to -> must be a pointer, so I tried to add a * to it (ent->*d_name) however then I get the error unexpected token *, how can I fix this?
#ifndef UTILIS_H_INCLUDED
#define UTILIS_H_INCLUDED "utilis.h"
#include <stdio.h>
#include <dirent.h>
char *connect(const char *pattern)
{
struct dirent ent;
char *d_name;
DIR *mgt = opendir("\\\\example\\windows7apps");
while ((ent = readdir(mgt)) != pattern)
{
puts(ent->d_name);
}
}
#endif
I read here that the second argument to -> must be a pointer,
That's wrong, the "first" argument, or, actually, the operand of the -> operator should be of pointer type.
In your case, ent is not a pointer type, so you cannot use the pointer member dereference operator ->. (you could have used the member dereference operator . instead).
Actually, in your code, ent should be a pointer, as per the return type of readdir(). So you better correct the type of ent to be of struct dirent *, then you can make use of -> on ent.
usually header files only contain data definitions and function prototypes. Your function definition should almost certainly be in a C file.
If you look at the function readdir it returns a pointer to a struct dirent so your variable ent should be a pointer
struct dirent *readdir(DIR *dirp);
struct dirent *ent;
That will fix your error invalid type argument of '->' (have struct dirent)

access members of a structure from void pointer inside a structure

I want to access members of a structure from void pointer inside a structure, I have tried the following code but it is giving error as "expected identifier before ‘(’ token". what should I change in printf statement? Thanks in advance.
#include "stdio.h"
struct
{
int date;
char *name;
}test;
struct
{
void *check;
}massage;
main()
{
test.date=21;
test.name="Nilesh";
massage.check =&test;
printf("date - %d , name - %s\n",massage.((struct test *)check)->date,massage.((struct test *)check)->name);
}
struct // anonymous struct type
{
int date;
char *name;
} test;
The above statement defines an anonymous struct type and creates a variable test of this struct type which has no name. Similarly, the below statement defines an anonymous struct type and creates a variable massage of this type -
struct // anonymous struct type
{
void *check;
} massage;
The typecast operator must have a type in the parentheses (type), not a variable name. Therefore, you must give the first struct a name (tag) so as to use the typecast operator. Also, the result of a typecast operator is an r-value and therefore it cannot be used with member selection .(dot) operator (it should be the name of the member). Therefore, the typecast operator should be applied after the value is fetched from the structure. Therefore, the following expression is wrong -
massage.((struct foo *)check)->date
// |____________________|
// |
// this should be the member name but it
// evaluates to a r-value - the result of
// the typecast operator assuming struct tag
// is foo
// it should instead be
((struct foo *)massage.check)->date
// dot operator has higher precedence than typecast
// so the struct member check is fetched first and
// it is typecast to type (struct foo *)
I suggest the following changes -
// standard headers should be
// enclosed in angle < > brackets
#include <stdio.h>
// give the structure a name so it can be
// used in typecasting
struct foo {
int date;
char *name;
} test;
// anonymous struct type
struct {
void *check;
} massage;
// return type of main should be int and
// parameter list should contain void
int main(void) {
test.date = 21;
test.name = "Nilesh";
massage.check = &test;
// fetch the struct member check and then
// apply typecast operator
printf("date - %d , name - %s\n", ((struct foo *)massage.check)->date,
((struct foo *)massage.check)->name);
return 0;
}
In your expression:
massage.((struct test *)check)->date
// ^^^ is variable not a data-type
there are two mistakes:
You can't type case into a variable, in your code test is a variable not a type so (struct test *) is wrong expression. You should name the user-defined type (as I have suggested below).
You are applying typecasting without accessing massage's pointer member. So in expression (struct test *)check, actually "check" is unknown variable. compiler will error you "check" is undeclared variable (thought test is not a datatype but the order of applying type casting is conceptually wrong).
I am suggesting a couple of correction try with it:
Name the stuct e.g. newtype
struct newtype // notice I given name to user defined datatype
{
int date;
char *name;
}test;
Then correct second and third argument in printf function as below
((struct newtype *)massage.check)->date
// ^^^^^^^^^^^^^^ notice
Similarly third argument in printf. First access member then type cast to correct type.
For full code refer Ajay's answer.
The struct definition is not want you want -- it defines an object test of an unnamed struct type. Try
struct testType
{
int date;
char *name;
} test;
and then cast to (testType *).

how to use malloc on a pointer correctly?

I have the following struct and tried to use malloc to create a new object dynamically. It seems to work now with object_ptr obj_ptr1 = malloc(sizeof(object_ptr)); This only assigns the pointer size of object_ptr to obj_ptr1 ? but how do you assign the size of the original struct _object_t in this case?
typedef struct
{
int struct_id;
void *(*function)(void *);
int status;
} _object_t;
typedef struct _object_t* object_ptr;
/* create a new object */
object_ptr obj_ptr1 = malloc(sizeof(object_ptr));
Typedefs for pointer types are often a bad idea, since they can make it difficult to tell whether a type name refers to a pointer type or not.
Suggestion:
typedef struct { /* ... */ } object_t;
object_t *obj1 = malloc(sizeof *obj1);
And if you want to allocate space for an array of N objects:
object_t *obj1 = malloc(N * sizeof *obj1);
Note that I've removed the leading underscore from the type name. Identifiers starting with underscores are reserved to the implementation; you shouldn't define them in your own code.
The malloc(sizeof *foo) idiom may take a little getting used to, but it means you don't have to specify the type name more than once, which avoids errors. (The *obj1 doesn't actually dereference obj1, since the operand of sizeof is not evaluated.)
In your code:
object_t obj1 = malloc(sizeof(object_t));
since object_t is a pointer type, you're allocating enough memory to hold a pointer object, not a structure object. (Using such similar names object_t and _object_t for the pointer and struct types, respectively, undoubtedly contributed to the confusion.)
The problem is in your malloc line. You must allocate sizeof(_object_t) not sizeof(object_t)

Resources