typedef struct item {
char *text;
int count;
struct item *next;
};
So I have this struct with nodes defined as above, but Im getting the error below and Im not able to figure out whats wrong.
warning: useless storage class specifier in empty declaration
};
I'm not sure, but try like that :
typedef struct item {
char *text;
int count;
struct item *next;
}item;
typedef is used to create a shorthand notation for an existing type in C. It is similar to #define but unlike it, typedef is interpreted by the compiler and offers more advanced capabilities than the preprocessor.
With its simplest form, typedef is given as
typedef existing_type new_type;
for instance,
typedef unsigned long UnsignedLong;
For example, if you trace the definition of size_t back to its root, you will see that
/* sys/x86/include/_types.h in FreeBSD */
/* this is machine dependent */
#ifdef __LP64__
typedef unsigned long __uint64_t;
#else
__extension__
typedef unsigned long long __uint64_t;
#endif
...
...
typedef __uint64_t __size_t;
and then
/* stddef.h */
typedef __size_t size_t;
which actually means, size_t is an alias for unsigned long long,depending on the 64-bit modal (LP64, ILP64, LLP64) your machines has.
For your question, you attempt to define a new type but do not name it. Don't let the struct item {..} definition confuse you, it is just a type you are declaring. If you replace the whole struct item {...} with a basic type, say with an int, and rewrite your typedef, you would end up something like this
typedef int; /* new type name is missing */
the correct form should be
typedef struct item {...} Item;
See the examples below for different structure definitions
#include <stdio.h>
/* a new type, namely Item, is defined here */
typedef struct item_t {
char *text;
int count;
struct item_t *next; /* you canot use Item here! */
} Item;
/* a structure definition below */
struct item {
char *text;
int count;
struct item *next;
};
/* an anonymous struct
* However, you cannot self-refence here
*/
struct {
int i;
char c;
} anon;
int main(void) {
/* a pointer to an instance of struct item */
struct item *pi;
/* Shorthand for struct item_t *iI */
Item *iI;
/* anonymoous structure */
anon.i = 9;
anon.c = 'x';
return 0;
}
The typedef is useless because you didn't give it a name. You cannot use the typedef in any way. That's why you get a warning, because the typedef is useless.
The struct is actually still usable without the warning if you remove the typedef keyword like this:
struct item {
char *text;
int count;
struct item *next;
};
You just need to include the 'struct' keyword in the variable declaration. i.e.
struct item head;
as other have pointed out if you include the name at the end of the struct definition then you can use it as the typedef and you get rid of the warning even without the struct keyword but this makes the first instance of 'item' superfluous i.e.
typedef struct {
char *text;
int count;
struct item *next;
} item;
item head;
will also get rid of the warning.
This is an oldie, but stumbled here because I had the same linker error.
I made the foolish mistake of naming a file with an extension .c, and should have been .cpp - created the SAME error - so watch out!
Renamed the file to have a .cpp extension, and the problem magically went away.
Took a while to figure that out, so happy to share my experience.
Related
I am writing a game in C. But I keep getting a number of errors. One prominent one is this. "Illegal Identifier: X" where X is the type of a variable inside a structure. An instance, Illegal Identifier: MapItem, is caused by the following code
typedef struct MapItem{
int item;
int count;
};
typedef struct MapTile{
MapItem item;
int x;
int y;
int tile;
Direction dir;
int drop;
};
The error is attached to the first line inside the MapTile struct. I would like to know why this error is occurring, and how to fix it.
The code segment was taken, in exact order, from map.h. Direction is an enum declared earlier in the same header.
Thank you all for answering. However, I did receive the answer I needed 4 hours ago.
Your typedef are incorrect. The syntax is:
typedef type typealias ;
So:
typedef struct
{
int item;
int count;
} MapItem;
typedef struct
{
MapItem item;
int x;
int y;
int tile;
Direction dir;
int drop;
} MapTile;
Note that types being aliased here are anonymous structs, the struct-tag is only required for self-referencing structs.
typedef is used to create an alias to another type (existing or defined in the same typedef statement).
Its general format is:
typedef existing_or_new_type alias;
The aliased type in your typedef is the new struct MapItem defined in the typedef statement but the alias is missing. This is the cause of the error.
You can use:
typedef struct MapItem {
int item;
int count;
} MapItem;
This statement declares the new type struct MapItem (the struct keyword is part of the type name) and the new type MapItem that is an alias of struct MapItem. This means that everywhere you can or have to use struct MapItem you can use MapItem instead.
If this seems confusing, you can use different names for the struct type and its alias. Or you can omit the name from the struct definition at all:
typedef struct {
int item;
int count;
} MapItem;
This way, MapItem is the name of an anonymous struct type and it is the only way to declare variables of this type.
Its my first publication and I'm studying C programming right now so I'm not an expert.
I've encountered that error compiling this lines (in a thread):
...
struct task_par *tp;
tp = (struct task_par *)arg;
a = tp->arg;
...
struct task_par is:
typedef struct
{
int arg;
int period;
int priority;
} task_par;
Note that "arg" is the argument of the thread
What's the correct type of "a"? because I've tried every type and it's still "error", so what else is wrong?
You don't define a struct task_par with the code you have shown. What you are defining is a typedef (a sort of new type) named task_par that is an alias for a certain anonymous struct type.
Your variable definition should simply say task_par *tp; in this case. If you prefer to use struct task_par, the way you have it now, you should change your struct definition to:
struct task_par
{ // ...
}
Or you can combine the two:
typedef struct task_par
{ // ...
} task_par_t;
Then you could define your variable either as struct task_par *tp; or as task_par_t *tp;.
The bottom line is that struct names and typedef names live in two different namespaces. You could even do typedef struct foo { /* */ } foo;, but some consider that bad form due to the potential for confusion...
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);
typedef struct _VIDEO_STREAM_CONFIG_CAPS
{
GUID guid;
ULONG VideoStandard;
SIZE InputSize;
SIZE MinCroppingSize;
SIZE MaxCroppingSize;
int CropGranularityX;
int CropGranularityY;
int CropAlignX;
int CropAlignY;
SIZE MinOutputSize;
SIZE MaxOutputSize;
int OutputGranularityX;
int OutputGranularityY;
int StretchTapsX;
int StretchTapsY;
int ShrinkTapsX;
int ShrinkTapsY;
LONGLONG MinFrameInterval;
LONGLONG MaxFrameInterval;
LONG MinBitsPerSecond;
LONG MaxBitsPerSecond;
} VIDEO_STREAM_CONFIG_CAPS;
Why not define structure VIDEO_STREAM_CONFIG_CAPS directly instead of involving _VIDEO_STREAM_CONFIG_CAPS?
Quite simply (at least for me) because some people like to be able to treat user defined types as "primary" types.
Just like I wouldn't like to have to say:
struct int i;
I prefer:
VIDEO_STREAM_CONFIG_CAPS vscc;
to:
struct VIDEO_STREAM_CONFIG_CAPS vscc;
In fact, I usually get rid of the structure tag altogether, preferring:
typedef struct {
GUID guid;
ULONG VideoStandard;
:
} VIDEO_STREAM_CONFIG_CAPS;
The only time I genarally use the tag is if I have to refer to the type within the type definition itself, such as in linked lists:
typedef struct sNode {
char paylod[128];
struct sNode *next;
} tNode;
That's because, at the time of creating the definition, tNode doesn't yet exist but struct sNode does (you can think of it as a simple sequencing thing if that makes it easier - struct sNode gets created on line 1 above, tNode on line 4, which means on line 3 where you create the next pointer, you have to use the structure name).
In the case you cite, the structure tag is superfluous at least in the code shown. Whether some other piece of the code declares a variable with the structure name rather than the typedef name is unclear.
In c, you have to put struct in front of a declaration of a struct type. Without this typedef, you'd have to write struct VIDEO_STREAM_CONFIG_CAPS each time you wanted to use it. With the typedef, you can say just VIDEO_STREAM_CONFIG_CAPS as you would in c++.
struct a {};
struct a A;
OR
typedef struct a {} a;
a A;
In that case, each time a variable of type VIDEO_STREAM_CONFIG_CAPS is declared, the following syntax would be required:
struct VIDEO_STREAM_CONFIG_CAPS vscc;
With typedef struct it is:
VIDEO_STREAM_CONFIG_CAPS vscc;