I have a problem defining my structure inside the union on Bison
I made a structure
typedef enum {Binary_Op,Uni_Op,Variable, Const} Tag_Type;
typedef struct tree
{
Tag_Type Tag;
union
{
struct
{
char op;
struct tree *left, *right;
}bin_op;
struct
{
char op;
struct tree *arg; /* negative or positive */
}uni_op;
char var;
int const_val;
}u;
}TREE_REC, *TR;
%}
%union
{
int y_int;
TR y_tree;
}
%type <y_tree> expr term factor assign
%token <y_int> CONST
%token <y_int> VAR
%%
but inside the union TR has an error. I don't understand why!! any help?
You need to define struct tree and TR in a header file that you #include before you #include "y.tab.h". The error message is telling you that you're trying to use TR before the compiler has seen a definition for it.
I'm a bit confused with your typedef struct tree {...} TREE_REC, *TR. I would have rather written :
typedef struct tree {...} TREE_REC; //Alias on struct tree
typedef TREE_REC * TR; //Definition of the pointer to a struct tree
The , in your typedef is disturbing me.
Can you test my solution, or just clarify the syntax of your typedef?
Related
I have the following code where a struct field depends on a struct field that is not declared yet, because that struct in turn might depend on the struct that I am trying to declare.
How can I design this so that it compiles? Or am I missing an obvious way to get rid of the union struct for keeping several struct definitions together?
typedef struct expression {
expression_type type;
union {
bool_expression bool;
identifier_expression ident;
integer_expression _int;
prefix_expression prefix;
infix_expression infix;
// TODO: Fix this
if_expression _if;
};
} expression;
typedef struct statement {
token token;
identifier name;
expression * value;
} statement;
typedef struct block_statement {
token token;
statement *statements;
} block_statement;
typedef struct if_expression {
token token;
expression condition;
block_statement *consequence;
block_statement *alternative;
} if_expression;
You can't, in this case.
if_expression contains an expression which in turn contains an if_expression. If you solve this problem by using pointers, you can reorder your definitions and use struct expression* to create a pointer to a struct that has not yet been defined.
You better remove the typedefs, at least initially, so you can better understand your types.
You should change your structs to point (rather than include) other structs, for example:
struct if_expression {
/* struct? */ token *token;
struct expression *condition;
struct block_statement *consequence;
struct block_statement *alternative;
}
Of course that will impose some judiciously use of malloc() and free() calls. In some cases you can later revert to inclusion (like token above, as it isn't expected that it points to your other structs, and copying tokens around is - perhaps - a cheap operation).
For the circularity of references you can forward declarations in C, that is you tell the compiler "hey, there is a struct named expression, whose internal structure you don't know yet, but bear with me, you will soon":
struct expression;
If you later decide to use typedef - so your code gets more streamlined - bear in mind that the structs can have a name, and typedefs define names, and those names don't share the same namespace. In examples:
typedef struct {
/* ...internal structure omited... */
} type_a;
typedef struct type_b {
/* ...internal structure omited... */
} type_b;
typedef struct struct_c {
/* ...internal structure omited... */
} type_c;
Here type_a is a type whose definition is an anonymous struct. And type_b is a type whose definition is struct type_b, that is a named (type_b) structure. And type_c is a type whose definition is struct struct_c, that is a named (struct_c) structure.
Now put it all together, you can:
/* forward all your structs */
struct expression;
struct if_expression;
struct block_statement;
/* typedef them all */
typedef struct expression expression;
typedef struct if_expression if_expression;
/* actually define them */
struct expression {
/* ... */
}
As a footnote, you can learn a lot about C language by understanding the difference between declaration and definition.
If you change expression condition; to expression *condition; in if_expression, and forward declare expression — typedef struct expression expression; at the top and then place struct expression { … }; at the bottom, the code should be OK.
/* Placeholder typedefs for undefined typedef names */
typedef int token;
typedef int identifier;
typedef int bool_expression;
typedef int identifier_expression;
typedef int integer_expression;
typedef int prefix_expression;
typedef int infix_expression;
typedef int expression_type;
/* The fixed code starts here */
typedef struct expression expression;
typedef struct statement
{
token token;
identifier name;
expression * value;
} statement;
typedef struct block_statement
{
token token;
statement *statements;
} block_statement;
typedef struct if_expression
{
token token;
expression *condition;
block_statement *consequence;
block_statement *alternative;
} if_expression;
struct expression
{
expression_type type;
union
{
bool_expression bool;
identifier_expression ident;
integer_expression _int;
prefix_expression prefix;
infix_expression infix;
if_expression _if;
};
};
expression expr = { 0 };
This compiles.
I need to declare a struct that both use one another.
For, example, how do I compile this?
z3 src # cat dependant.h
typedef struct egg_t egg_t;
typedef struct chicken_t chicken_t;
typedef struct egg_t {
int egg_num;
struct chicken_t chicken;
} egg_t;
typedef struct chicken_t {
int chicken_num;
struct egg_t egg;
} chicken_t;
z3 src # gcc -c dependant.h
dependant.h:6:20: error: field 'chicken' has incomplete type
dependant.h:7:3: error: redefinition of typedef 'egg_t'
dependant.h:1:22: note: previous declaration of 'egg_t' was here
dependant.h:12:3: error: redefinition of typedef 'chicken_t'
dependant.h:2:26: note: previous declaration of 'chicken_t' was here
z3 src #
You can create pointers to incomplete types (nixing the typedefs since they don't add anything):
struct egg_t;
struct chicken_t;
struct egg_t {
int egg_num;
struct chicken_t *chicken;
};
struct chicken_t {
int chicken_num;
struct egg_t *egg;
};
Of course, the right answer is to avoid this kind of circular dependency in the first place, but that's not always possible.
I'm trying to create a struct to be used in a Linked List that looks like this:
#ifndef MYGREP_H
#define MYGREP_H
typedef struct occurrenceType Occurrence;
struct occurrenceType {
char* line;
int lineNumber;
int wordNumber;
Occurrence *next;
};
#endif
but when I try to allocate memory using sizeof(Occurrence) I get the error "Invalid application of 'sizeof' to incomplete type 'Occurrence.' I've tried several different structure declaration formats with no luck. Can someone tell me what I'm doing wrong? Thanks!
Your first struct typedef declaration:
v
typedef struct occurenceType Occurrence;
^
has one 'r' on "occurencyType" but your definition:
vv
struct occurrenceType {
^^
char* line;
int lineNumber;
int wordNumber;
Occurrence *next;
};
has two 'r's.
Struct is user defined data type in c. Before the declaration of occurrenceType you are trying to use it and hence before its declaration or definition if you try to use it then it is an error. Your code should be
#ifndef MYGREP_H
#define MYGREP_H
struct occurrenceType {
char* line;
int lineNumber;
int wordNumber;
Occurrence *next;
};
typedef struct occurrenceType Occurrence;
#endif
First declaration then use it. Another it may be some spell mismatch so try to use this
I am using Kdevelop in Kubuntu.
I have declared a structure in my datasetup.h file:
#ifndef A_H
#define A_H
struct georeg_val {
int p;
double h;
double hfov;
double vfov;
};
#endif
Now when I use it in my main.c file
int main()
{
georeg_val gval;
read_data(gval); //this is in a .cpp file
}
I get the following error:
georeg_chain.c:7:3: error: unknown type name 'georeg_val'
(This is in the georeg_val gval; line)
I would appreciate if anyone could help me resolve this error.
In C one has two possibilities to declare structure:
struct STRUCT_NAME {} ;
or
typedef struct {} STRUCT_ALIAS;
If you use first method (give struct a name) - you must define variable by marking it explicitly being a struct:
struct STRUCT_NAME myStruct;
However if you use second method (give struct an alias) then you can omit struct identifier - compiler can deduce type of variable given only it's alias :
STRUCT_ALIAS myStruct;
Bonus points:
You can declare struct with both it's name and alias:
typedef struct STRUCT_TAG {} STRUCT_TAG;
// here STRUCT_NAME == STRUCT_ALIAS
Then in variable definition you can use either first or second method. Why both of two worlds is good ? Struct alias lets you to make struct variable definitions shorter - which is a good thing sometimes. But struct name let's you to make forward declarations. Which is indispensable tool in some cases - consider you have circular references between structs:
struct A {
struct B * b;
}
struct B {
struct A * a;
}
Besides that this architecture may be flawed - this circular definition will compile when structs are declared in the first way (with names) AND struct pointers are referenced explicitly by marking them as struct.
If you have to define a new type, you have to write:
typedef struct {
int p;
double h;
double hfov;
double vfov;
} georeg_val ;
Then you can use georeg_val as a new type.
Defining a struct type (on this example, a binary search tree struct):
struct tree {
int info;
struct tree *left;
struct tree *right;
}
typedef struct tree treeNode;
Declaring a function eg.:
treeNode *insertElement(treeNode *treeA, int number);
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;
};