Given the following struct,
typedef struct tCard {
CardClass class;
void *proto;
} Card;
typedef struct tCardPath {
PathType path_type;
struct tPath path;
Goal goal;
} CardPath;
Is it possible to access the element pointed by a pointer to struct (proto) using macros, like this?
((CardPath*)(trial[i].proto))->element1; // this works
CARD_PROP(trial[i], Path, element1); // the goal
I tried this, but this gives error: expected identifier before ‘(’ token when compiling,
#define PROTO(C) (C).proto
#define CARD_PROP(C, CARD, PROP) (((Card##CARD *)(PROTO(C)))->(PROP))
EDIT:
Tried this, still doesn't work
#define CARD_PROP(C, CARD, PROP) ((Card##CARD *)(PROTO(C))->PROP
The problem is that you can't put members of a struct in parentheses. Your macro expands to:
((CardPath*)(trial[i].proto))->(element1)
^^^^^^^^^^
Which shouldn't have parentheses where I marked above.
Related
How can I fix this warning?
typedef void (*VF_A)(PST_A); // Warning here: parameter names (without types) in function declaration
typedef struct ST_A_ {
...
VF_A vf_a;
} ST_A, *PST_A;
This question is similar to Resolve circular typedef dependency?, but yours is slightly different in that you have a pointer to a function instead of a struct. Use the strategy from this answer.
The idea behind the problem is that you are trying to declare a new type and also define a struct at the same time. The solution is to separate these two:
typedef struct ST_A_ ST_A, *PST_A; // PST_A points to some struct, defined later
typedef void (*VF_A)(PST_A); // use PST_A to define VF_A
struct ST_A_ { VF_A vf_a; }; // now define the struct PST_A points to
I have set-up structs like so in a C program:
typedef struct header block_header;
struct header {
size_t size;
block_header *next_pointer;
block_header *prev_pointer;
};
However, when I run any expression like the following:
int myinit()
{
block_header *p = init_heap_segment(BLOCK_HEAD_SIZE);
// etc etc
}
It gives me several errors for each function that it is declared in:
allocator.c: In function ‘myinit’:
allocator.c:37:38: error: ‘header’ undeclared (first use in this function)
allocator.c:37:38: note: each undeclared identifier is reported only once for each function it appears in
allocator.c: In function ‘function’:
allocator.c:67:2: error: unknown type name ‘header’
What is the problem with the way that it is set-up? How do I make these errors go away?
EDIT: Definition of:
#define BLOCK_HEAD_SIZE (ALIGN(sizeof(header)))
This is your problem
#define BLOCK_HEAD_SIZE (ALIGN(sizeof(header)))
There's no such type as header in your program, which is what the compiler is telling you. You have defined type struct header and you have defined a typedef name block_header for it. So choose whichever you prefer: either sizeof(struct header) or sizeof(block_header). But not sizeof(header).
In C++ language defining a struct header type would also introduce typename header into the program. But not in C. In C the type defined by struct header is called struct header - two words. It cannot be shortened to a mere header.
In your program, there is no such type called header. But you are using
#define BLOCK_HEAD_SIZE (ALIGN(sizeof(header))) // problem
It should be-
#define BLOCK_HEAD_SIZE (ALIGN(sizeof(struct header)))
or
#define BLOCK_HEAD_SIZE (ALIGN(sizeof(block_header)))
Whenever you are calculating size like this, make sure that you are using correct parameters!
Why not just do:
typedef struct block_header {
size_t size;
block_header *next_pointer;
block_header *prev_pointer;
}header;
and with that you can do:
header *p = init_heap_segment(BLOCK_HEAD_SIZE);
with a new declaration for init_heap_segment() where it returns 'header *' instead of 'struct block_header *'. Just much cleaner.
What I want to accomplish: I want to use a typedef'd function pointer inside of a typedef'd struct where the function pointer takes a struct pointer as an argument (i.e. something like an 'object method' which takes a self-reference to the 'object').
I have this C code (simplified, hopefully not oversimplified):
typedef struct MYSTRUCT myStruct;
typedef void (*getSomething)(myStruct*);
typedef struct MYSTRUCT {
getSomething get_something;
};
void get_property() {
myStruct *structure = NULL;
}
So what I think I'm doing is: forward declare the struct, use that declaration in the function pointer typedef, then declare the actual struct using the typedef'd function pointer.
This code compiles with the intel compiler on linux (and seems to do the intended thing) but the Visual compiler throws an error:
error C2275: 'myStruct' : illegal use of this type as an expression
see declaration of myStruct
Is there a way to make the VC accept my intended construct?
typedef struct MYSTRUCT {
getSomething get_something;
};
should be
struct MYSTRUCT {
getSomething get_something;
};
struct MYSTRUCT; // Forward declare the struct
typedef struct MYSTRUCT myStruct; // define the typedef;
typedef void (*getSomething)(myStruct*); // use the typedef;
struct MYSTRUCT { // define the struct
getSomething get_something;
};
void get_property() { // use the typedef again.
myStruct *structure = NULL;
}
// Warning: I didn't actually compile that, and I'm going from memory.
Sorry. I just realized this was not a problem of my forward declaration but rather because what I really did in my actual code was this:
void get_property() {
some = assignment_statement;
myStruct *structure = NULL;
}
I.e. I accidentally put my variable declaration + definition below the first code statement. So indeed, I had oversimplified my code fragment. Sorry for this.
I am trying to define two structures in C when the second struct uses the first as an array member and has two pointer members of itself.
Visual Studio does not like my code:
syntax error : '}'
syntax error : identifier 'tokenListNode'
syntax error : missing '{' before '*'
any idea how to solve this?
--> Please note that the errors appear with or without the declarations I added at the beginning of the code.
--> In addition, if someone can explain to me what is the difference between the identifier
before and after the struct's curly brackets, I'll be grateful.
Below is the code:
#define ARRAY_SIZE 100
struct tokenListNode;
struct TOKEN_LIST_NODE;
enum TOKEN_TYPE
{
id = 0,
INT_NUM,
INT_REAL,
ASSIGNMENT_OP,
RELATION_OP,
ARITHMETIC_OP
} tokenType;
typedef struct TOKEN
{
char* lexema;
enum TOKEN_TYPE type;
int lineNumber;
} token;
typedef struct TOKEN_LIST_NODE
{
token tokenArray[ARRAY_SIZE];
tokenListNode* prevNode;
tokenListNode* nextNode;
int tokenCounter;
}tokenListNode;
You do not define tokenListNode until after you use it. Change to the following:
typedef struct TOKEN_LIST_NODE tokenListNode;
struct TOKEN_LIST_NODE
{
token tokenArray[ARRAY_SIZE];
tokenListNode* prevNode;
tokenListNode* nextNode;
int tokenCounter;
};
The definition of a structure is composed of the keyword struct; the "struct tag"; and the struct members
struct tag { int member1; /* &c */ };
You can leave the tag out and create an unnamed structure ... why you would do so is another matter: you can't refer to the structure without a struct tag!
struct { int member1; /* &c */ };
Also, you can take any type and give it another name using typedef
typedef old_type new_name;
as in
typedef struct tag { int member1; /* &c */ } tag;
/* <------------ old type ------------> <new name> */
The above line defines a struct (named struct tag) and, at the same time, gives that type a new name: tag
what is the difference between the identifier before and after the struct's curly brackets
That's the result of mixing definition of struct and typedef. The name before the {} is the "tag" of the structure, the name after the {} is the new name for the type being typedef'd.
You need to use the struct tag instead of it's typedef'ed version when referring to itself.
struct TOKEN_LIST_NODE
{
token tokenArray[ARRAY_SIZE];
struct TOKEN_LIST_NODE* prevNode;
struct TOKEN_LIST_NODE* nextNode;
int tokenCounter;
};
typedef void (callback)(int *p1, sStruct *p2);
typedef struct _sStruct
{
callback *funct;
}sStruct;
I have the following declaration, in C. How can I compile this recurrent declaration without receiving any error ?
For the moment I receive: syntax error before '*' token on first line.
You can forward-declare the structure:
/* Tell the compiler that there will be a struct called _sStruct */
struct _sStruct;
/* Use the full name "struct _sStruct" instead of the typedef'ed name
"sStruct", since the typedef hasn't occurred yet */
typedef void (callback)(int *p1, struct _sStruct *p2);
/* Now actually define and typedef the structure */
typedef struct _sStruct
{
callback *funct;
} sStruct;
Edit: Updated to match the question's change of type names.
Also, I strongly suggest that you do not give the struct the identifier _sStruct. Global names beginning with a _ are reserved names, and using them for your own identifiers could cause undefined behavior.