“redefinition of 'foo' as different kind of symbol” - c

I’m trying to refactor and bring-over some old code, and I ran across something like this:
struct foo;
typedef struct foo * foo;
When attempting to compile it, I get the following sort of error:
Source/Types/Types.h:27:18: error: redefinition of 'foo' as different kind of symbol
typedef struct foo * foo;
^
Anybody know what’s causing this? I haven’t touched the code in a long time, but I certainly don’t remember any errors relating to that. It’s some of the most core code in the codebase, everything depends on it; I don’t see how I could possibly have missed such a glaring error, if it is indeed an error. Since the original foo is a “struct tag” (only a sane reference after the struct keyword), how can it conflict with my new foo typedef’d type?
Edit 1: Here’s the entire actual file, maybe I’m missing something, but it seems pretty straight-forward. It dumps a slew of the same errors described above, one for each type:
# if !defined(TYPE_DECLARATIONS)
# define TYPE_DECLARATIONS
# include "Core.h"
# warning "in Core.h"
static int class = 0; // to prove I’m not compiling as C++
struct e(fork);
typedef struct e(fork)* e(fork);
struct e(execution);
typedef struct e(execution)* e(execution);
struct e(thing);
typedef struct e(thing) e(thing);
struct e(typeRepresentation);
typedef struct e(typeRepresentation)* e(typeRepresentation);
struct e(typeRepresentation) {
void * family;
char name[64]; };
struct e(thing) {
void * const pointer;
e(typeRepresentation) const isa; };
# endif //!defined(TYPE_DECLARATIONS)
(Also, ignore the e() macro; it’s a noop in this case.)

Ah, I solved my own problem. I managed to screw up my e() macro such that it was literally preforming a noop, removing the code in question. :O
I’m an idiot. Sorry for wasting everyone’s time.

Are you now compiling this as C++, whereas it used to be compiled as C?
In C++, struct and enum tags live in the same namespace as other type names.

you associate the name foo with two different types. struct foo and a pointer to struct foo are different types.

Related

Storage size of ' ' isn't know [duplicate]

I'm a bit new to C and I'm having a bit of trouble with a project I'm currently working on. Essentially I have the following files: main.c, alarm.c, alarm.h
I have a struct declaration in alarm.c that looks like:
#define STRLEN 150;
struct alarmparams
{
char time[STRLEN];
char duration[STRLEN];
char snooze[STRLEN];
char port[STRLEN];
};
In main.c I have:
#include <stdio.h>
#include <string.h>
#include "alarm.h"
int main(int argc, char *argv[])
{
struct alarmparams params;
printf("%s, %s\n", params.time, params.duration);
}
And in alarm.h I have:
struct alarmparams;
Right now when I go to compile I get the following error:
error: storage size of ‘params’ isn’t known
I've looked through other posts regarding this error, so I have done a bit of research on this already. I've also tried some of the suggested solutions and it's either I get the exact same error or I got more on top of it. I'm at a lose as to how to fix this.
Is there something I'm missing? Did I declare something incorrectly?
In general should structs be declared in the header file or the c file? Or does it even matter? What's the different between:
struct foo {...};
and
typedef struct foo {...};
struct alarmparams;
is the declaration of an incomplete type. You can create a pointer to an object of this type but you cannot declare an object of this type or take its size until it has been completed. You have to make its complete declaration visible in main.c to declare an object of its type.
If you use the type in both alarm.c and main.c, just declare it in alarm.h and include alarm.h in main.c.
For you second question, the difference between:
struct foo {...};
and
typedef struct foo {...} foo_;
is in the latter case you also declare an alias foo_ for the type name struct foo.
You have to declare the structure in the header file alarm.h.
At the moment, when you include alarm.h, the code in main doesn't see the structure composition, all it sees is struct alarmparams;, so it doesn't know how long it is. How can you allocate space for something that you don't know how much space it takes?
typedef struct foo { ... }; is invalid: typedef expects you to provide an alias for a type. typedef struct foo { ... } foo_t; would be correct.
typedef is a storage class specifier, thus, you can think of it as any other regular declaration. Imagine you want an alias foo for the type bar: just declare a variable of type bar and call it foo. Now, prepend a typedef keyword behind, and you are done. Even complicated typedefs can be easily understood with this simple approach. Since struct foo { ... }; would be an invalid declaration for a variable (no name is provided), so is typedef struct foo { ... };.
In general, declare structures in the header file when you will reuse them in other source files. If you don't plan on doing so, declaring them on the .c file should be fine.
In addition to the other answers, the value of STRLEN must be known at compile time (it most likely is in this case, but just in case).

Co-Dependent Definitions in C

Suppose we have a function pointer on a struct, which has the struct itself as the first argument, a typical callback scenario.
typedef void (*callback_type)(my_struct_type *mst, int whatever);
typedef struct {
// lots of fun stuff
callback_type notify_me;
} my_struct_type;
This produces a compiler error on the first typedef, as one might expect. error: unknown type name my_struct_type. Reversing the definitions produces the same result, but the unknown type is callback_type.
The easy solution is to do the following:
typedef struct my_struct_type_S {
// lots of fun stuff
void (*notify_me)(my_struct_type_S *mst, int whatever);
} my_struct_type;
However, doing this elides the function pointer type definition, which it would be nice to be able to easily refer to later, and use for static type checks, nice error messages, etc.
Any suggestions on how to resolve this?
Edit on "possible duplicate":
This scenario involves function pointer typedefs that are arcane to many people. I think this is a good example for that case, and additionally, the accepted answer is very clean, clear, and simple.
You can do this by giving the struct a tag and using a forward declaration of the struct. Then you can use the typedef for the function pointer, and subsequently complete the definition of the struct.
typedef struct my_struct_type_S my_struct_type;
typedef void (*callback_type)(my_struct_type *mst, int whatever);
struct my_struct_type_S {
// lots of fun stuff
callback_type notify_me;
};
You need to define the tag of the struct
typedef void (*callback_type)(struct _my_struct_type *mst, int whatever);
typedef struct _my_struct_type {
// lots of fun stuff
callback_type notify_me;
} my_struct_type;

C Struct Formatting/alias

I'm a beginner in C and I came across some codes in a header file that I'm not sure what style it uses and what it means.
typedef struct tActiveObject *testActiveObjectPtr;
typedef struct tActiveObject {
ActiveObject ao;
int state;
} testActiveObject, *testActiveObjectPtr;
Why do we need to create a pointer as an alias i.e. testActiveObject and *testActiveObjectPtr? And is this just some C style that I am not aware of?
Thanks.
If the both those typedefs occur in the same header file, then the code doesn't make any sense. In that case, the first typedef is completely superfluous and the whole code could get replaced with
typedef struct {
ActiveObject ao;
int state;
} testActiveObject, *testActiveObjectPtr;
Otherwise if the typedefs were in different files, the code might have been a failed attempt to create a pointer to an incomplete type, but it doesn't look like that's the case. The struct tag is superfluous, but also smells like a failed attempt to create a self-referencing struct.
Also, good programming practice dictates that you never hide a pointer behind a typedef.
So it would seem the whole code was created by a rather confused person who didn't quite know what they were doing. If possible, throw the code away and replace it with:
typedef struct {
ActiveObject ao;
int state;
} testActiveObject,
...
testActiveObject* ptr; // whenever you need a pointer to this type

struct in C: Error storage size of 'params' isn't known

I'm a bit new to C and I'm having a bit of trouble with a project I'm currently working on. Essentially I have the following files: main.c, alarm.c, alarm.h
I have a struct declaration in alarm.c that looks like:
#define STRLEN 150;
struct alarmparams
{
char time[STRLEN];
char duration[STRLEN];
char snooze[STRLEN];
char port[STRLEN];
};
In main.c I have:
#include <stdio.h>
#include <string.h>
#include "alarm.h"
int main(int argc, char *argv[])
{
struct alarmparams params;
printf("%s, %s\n", params.time, params.duration);
}
And in alarm.h I have:
struct alarmparams;
Right now when I go to compile I get the following error:
error: storage size of ‘params’ isn’t known
I've looked through other posts regarding this error, so I have done a bit of research on this already. I've also tried some of the suggested solutions and it's either I get the exact same error or I got more on top of it. I'm at a lose as to how to fix this.
Is there something I'm missing? Did I declare something incorrectly?
In general should structs be declared in the header file or the c file? Or does it even matter? What's the different between:
struct foo {...};
and
typedef struct foo {...};
struct alarmparams;
is the declaration of an incomplete type. You can create a pointer to an object of this type but you cannot declare an object of this type or take its size until it has been completed. You have to make its complete declaration visible in main.c to declare an object of its type.
If you use the type in both alarm.c and main.c, just declare it in alarm.h and include alarm.h in main.c.
For you second question, the difference between:
struct foo {...};
and
typedef struct foo {...} foo_;
is in the latter case you also declare an alias foo_ for the type name struct foo.
You have to declare the structure in the header file alarm.h.
At the moment, when you include alarm.h, the code in main doesn't see the structure composition, all it sees is struct alarmparams;, so it doesn't know how long it is. How can you allocate space for something that you don't know how much space it takes?
typedef struct foo { ... }; is invalid: typedef expects you to provide an alias for a type. typedef struct foo { ... } foo_t; would be correct.
typedef is a storage class specifier, thus, you can think of it as any other regular declaration. Imagine you want an alias foo for the type bar: just declare a variable of type bar and call it foo. Now, prepend a typedef keyword behind, and you are done. Even complicated typedefs can be easily understood with this simple approach. Since struct foo { ... }; would be an invalid declaration for a variable (no name is provided), so is typedef struct foo { ... };.
In general, declare structures in the header file when you will reuse them in other source files. If you don't plan on doing so, declaring them on the .c file should be fine.
In addition to the other answers, the value of STRLEN must be known at compile time (it most likely is in this case, but just in case).

Why often a struct's tagName differs from the typedef's name?

Sometimes I see code like this (I hope I remember it correctly):
typedef struct st {
int a; char b;
} *stp;
While the usual pattern that I familiar with, is:
typedef struct st {
int a; char b;
} st;
So what's the advantage in the first code example?
You probably mean this:
typedef struct ST {
/* fields omitted */
} *STP;
The asterisk is at the end of the statement. This simply means "define the type STP to be a pointer to a struct of this type". The struct tag (ST) is not needed, it's only useful if you want to be able to refer to the struct type by itself, later on.
You could also have both, like so:
typedef struct {
/* fields omitted */
} ST, *STP;
This would make it possible to use ST to refer to the struct type itself, and STP for pointers to ST.
Personally I find it a very bad practice to include the asterisk in typedefs, since it tries to encode something (the fact that the type is a pointer) into the name of the type, when C already provides its own mechanism (the asterisk) to show this. It makes it very confusing and breaks the symmetry of the asterisk, which appears both in declaration and use of pointers.
It's a habit that stems from the time when typedef names and struct tagnames were in the same namespace. See http://blogs.msdn.com/oldnewthing/archive/2008/03/26/8336829.aspx
I think you are talking about :
typedef struct{
int a;
char b;
} object, *objectPointer;
This means that (new) type objectPointer is a pointer to struct (object) defined above. Its easy to declare pointers to object struct this way. For instance,
objectPointer A = (objectPointer)malloc(sizeof(object));
A->a = 2;
Now, A is a pointer to struct object and you can access its variables as described above.
In case, objectPointer was not defined,
struct object *A = (struct object *)malloc(sizeof(object));
A->a = 2;
So, I guess objectPointer is more intuitive and easy to use.
I hope that the first code would say a compiler error ,
I see no good reason for the typedef name be different from the tag name.
Now, the reason for which the tag name needs to be typedefed if you don't want to use
struct tag v;
but
tag v;
is probably an historical one. For as long as I remember, C had typedef but I don't know if it was true when struct have been introduced (handling of typedef is a nuisance in the C grammar). In the old code I've seen, using typedef for struct isn't done, and there are things like unix
struct stat;
int stat(const char*, struct stat*);
which would break with an automatic typedef. One those are introduced, changing is quite difficult (yes, C++ has automatic typedef but C++ has special wording to handle that case of overloading and it would be yet another complication).

Resources