Defining an enum in C - c

I am a little bit surprised the following code does not compile. Can you shed some light on it? (header file)
enum CarType_e {
CAR_BMW = 0,
CAR_KIA,
CAR_HONDA,
CAR_FORD,
CAR_MERCEDES
};
int build_car(CarType_e type);
and then I get the following error:
In file included from car.c:19:0:
car.h:35:16: error: unknown type name ‘CarType_e’
This is gcc version 4.7.3

You have two choices, use
typedef enum {
CAR_BMW = 0,
CAR_KIA,
CAR_HONDA,
CAR_FORD,
CAR_MERCEDES
} CarType_e;
Or, you can use -
int build_car(enum CarType_e type);
I tested both with gcc on linux.

In C, custom types (enums, unions, and structs) each have their own naming scope.
You need to write int build_car(enum CarType_e type);.
This also means there is no point in the _e suffix.
Alternatively, you can use typedef.

You need to say enum CarType_e wherever you use it:
int build_car(enum CarType_e type);
Or typedef the enum.
typedef enum {
CAR_BMW = 0,
CAR_KIA,
CAR_HONDA,
CAR_FORD,
CAR_MERCEDES
} CarType_e;

You need to tell the compiler that you are using an enum by specifying its tag along with the enum keyword. Otherwise how would the compiler resolve an ambiguity like
struct foo { int x; char y; };
enum foo { CAR, BIKE, ROCKET };
union foo { int x; char y; };
int build_car (foo x); /* A struct foo or an enum foo or a union foo? */
Note that structs, enums and unions all have a separate tag name space, so I am free to reuse the same tag name for each of them as shown above.
Requiring the tag name as in
int build_car (enum foo x);
int build_bike (struct foo x);
int build_rocket (union foo x);
makes this non-ambiguous for the compiler.
And don't bother with typedefs for structs/unions; they are useless and only the unenlightened would consider them. Yes, that's a strong opinion. All they do is save you from writing struct in a few places--that's some information you rather want to know about.

Related

Why must a struct member always have an identifier?

Why must a struct member always have an Identifier? The answer of course is because that is how the language is defined, but I'd like to understand the reason behind it.
typedef union {
int a;
struct {
int a; //Why is an identifier necessary here?
int b;
} s;
} u;
There are grammar complications here. Consider int a, b, c;. That declares three objects. int a, b; declares two, and int a; declares one. So how many should int; declare? When a declaration with no declarator appears in other contexts, it does not declare any object. For example, struct foo { int x; }; defines the type struct foo, but it does not declare an object of that type.
We could make an exception for declarations in structures, and say that, if they have no declarators, then they declare one unnamed member. But then we are introducing another special case in to the grammar. Then struct foo { int x; };, which has no declarator, would declare a member object of type struct foo when it appears inside a structure definition, but it would not declare any object when it appears outside of a structure definition.
So this adds complications to the language. And it is not necessary; somebody who wants a member in a structure can always give it a name and can choose a name that will not interfere with other code.
Actually, bit field members do not need a name, at least according to gcc -std=c99 -Wall -Wextra -pedantic, which gives no warning when compiling this code:
struct Foo
{
char x;
unsigned :8;
};
If you really don't want to have an identifier for a member that isn't a bit-field, you can name it something like _reserved0 to explicitly show that this is just reserved space that you don't want to access from your code.
I don't know the opinions of the people who wrote the C standard. Maybe they were thinking a struct member without a name was almost always a bug (i.e. the programmer forgot the name), and they wanted to help people catch those bugs, but they made a few exceptions to the rule.
//Why is an identifier necessary here?
This a is distinct from the a outside the structure. The compiler needs to know which one you want to access
If you use distinct names you can use anonymous structure in your union
typedef union {
int a;
struct {
int b;
int c;
};
} u;
u foo(int x, int y, int z)
{
u un;
u.a = x;
u.b = y;
u.c = z;
}

typedef struct but keep new type namespaced under keyword 'struct'

How can I typedef a struct but still keep the new type namespaced under the keyword 'struct'?
example:
struct foo {
int x;
};
typedef struct foo struct bar;
int main(void) {
struct bar bar;
bar.x = 10;
return 0;
}
but this doesn't work obviously.
Here are the errors if anyone is curious:
main.c:5:20: error: two or more data types in declaration specifiers
typedef struct foo struct bar;
^
main.c:5:27: warning: useless storage class specifier in empty declaration
typedef struct foo struct bar;
^
main.c: In function 'main':
main.c:9:13: error: storage size of 'bar' isn't known
struct bar bar;
How can I typedef a struct but still keep the new type namespaced under the keyword 'struct'?
So, it seems that you want to define a structure alias for another structure type.
This is not possible with typedef as it creates a single word alias. The new alias can't be consisted of multiple white space separated words.
But you can use a single name like struct_bar with struct implemented inside of the name to show that bar is a structure.
#include <stdio.h>
struct foo {
int x;
};
typedef struct foo struct_bar;
int main(void) {
struct_bar bar;
bar.x = 10;
return 0;
}
How can I typedef a struct but still keep the new type namespaced under the keyword 'struct'?.
You cannot. A namespace is a declarative region that provides a scope to the identifiers (names of the types, function, variables etc) inside it. The concept of Namespace as it is defined within C++, is not inherent in C.
So, if you are okay with minor changes in your requirements, instead of doing something unnatural, use a simple typedef:
Instead of this:
struct foo {
int x;
};
do this:
typedef struct {
int x;
}foo;
Then this will work:
typedef foo bar;
int main(void )
{
bar b;
b.x = 10;
return 0;
}
Note: Although namespaces are not inherent in in C, as they are in C++, there are some interpretations eg: as discussed here, that argue the point.
C doesn't have any type of support for namespaces (at least not in the sense that C++ does).
When you create a typedef, the new type name is a single identifier, not multiple words. So struct bar can't be an alias for another type. You would have to call it bar or some other one-word name.
You can't. This isn't how it works.
You cannot "create" a type whose name is more than one word, nor can you refer to a type alias using the keyword struct.
The purpose of writing struct, in this context, is to refer to a struct type by a name that wasn't introduced as an alias. The keyword is there to say that that's what you want to do. But it's not part of the name; it cannot be part of the name.
Fortunately, there's no reason to need or even want this.
I found a solution that works for cygwin:
struct foo {
int x;
};
struct bar {
struct foo;
};

Declare a struct in C without defining it

I'd like to declare a struct in C without defining it at the same time (i.e. to separate interface and implementation) so others can include this in their projects and define it to their needs (it is only used as a parameter in my code). Thus, I'd like to know if this is:
A) Possible (maybe just using macros)?
B) Considered good practise (in my particular circumstance)?
B would be hard to answer without context (and is still subjective) so I'd only like it examined against any common pre-existing patterns in C for addressing the given context (if any). I have the following code:
typedef struct {
bool logged_in;
} Foo;
That I would like as this (pseudo code):
typedef struct Foo;
So this declaration can then be defined by the person who is including this in their project. In my code I am only using it as a parameter without trying to access the properties it contains, like so:
bool bar(Foo* foo) {
//...
}
Thanks.
Forward-declare it like this:
typedef struct Foo Foo;
Then define it with it's ‘full name’:
struct Foo {
…
};
Or you can just forward-declare the ‘full name’:
struct Foo;
And use that:
bool bar(struct Foo *foo) {
…
}
Did you try it? This compiles for me with no warnings on GCC:
typedef struct Foo_ Foo;
int bar( Foo *foop )
{
return 1;
}
I don't know any reason why you wouldn't want to do it.

using pre-defined structs anonymously in gcc?

In gcc it is possible to create an anonymous struct, like this:
struct test2 {
struct {
int x;
int y;
};
int z;
};
But when I try to do the same thing with a pre-defined version of the anonymous struct, it fails:
struct test1 {
int x;
int y;
};
struct test2 {
struct test1;
int z;
};
The reason I want to do this is that I want to define a struct which contains a set of function pointers corresponding to "member functions" of a C class. If I don't include the struct anonymously, then I wind up having to do something obnoxious like this:
object->API->function(object,...);
which just plain doesn't work for some things I need to do (for instance, since "object.API" doesn't match "object", it makes it difficult or impossible to do automatic bindings from other languages which support hiding of the object pointer.)
At the moment, I just copy/paste the functions, but this is tedious and error prone. I could use the C pre-processor, but it seems just ugly to create a macro which has a bunch of function prototypes in it.
struct test1 is the name of the type of the struct. You are lacking a name for the field (and you cannot have "anonymous" fields other than inline-defined structs or unions).
struct test2 {
struct test1 myStructTest1;
int z;
};
EDIT: Apparently there's a GCC extension that allows you do that: -fms-extensions
Unless -fms-extensions is used, the unnamed field must be a structure or union definition without a tag (for example, struct { int a; };'). If -fms-extensions is used, the field may also be a definition with a tag such asstruct foo { int a; };', a reference to a previously defined structure or union such as `struct foo;', or a reference to a typedef name for a previously defined structure or union type.
struct s1 { int a; };
struct s2 { struct s1; };

Compact access to variables in nested structures

Given this simple C code:
struct {
struct a {
int foo;
};
struct b {
char *bar;
};
} s;
I am wondering whether there is a way to access a variable in one of the nested structures in a more compact way than s.a.foo = 5, for instance.
First, notice that your example is not standard C89 (but it is acceptable by some compilers when you ask for some language extensions. With GCC you'll need to extend the accepted C dialect with the -fms-extensions flag to the compiler). You are using unnamed fields. A more standard way of coding would be:
struct a {
int foo;
};
struct b {
char* bar;
};
struct {
struct a aa;
struct b bb;
} s;
Back to your question, no, there is no other way. However, you might use preprocessor macros, whcih could help. For instance, assuming the above declarations, you could
#define afoo aa.foo
#define bbar bb.bar
and then you can code s.afoo instead of s.aa.foo
You might also define macros like
#define AFOO(X) (X).aa.foo
and then code AFOO(s)
Using such preprocessor macros does have some annoyance: with my example, you cannot declare anymore a variable (or formal argument, or field, or function) named afoo
But I am not sure you should bother. My personal advice & habit is to give longer and often unique names to fields (and also to name struct a_st my struct-ures). Take advantage of the auto-completion abilities of your editor. Don't forget that your code is more often read than written, so use meaningful names in it.
There is not. You have to specify the path the the memory address you wish to reference.
You can't cast structs directly, but you can cast pointers to structs. So if you have this stuct:
typedef struct {
struct {
int foo;
} a;
struct {
char bar;
} b;
} s;
You can create a struct like this:
typedef struct {
int foo;
char bar;
} sa;
Now when you create the struct, stash a pointer to it:
s myS;
myS.a.foo = 123;
myS.b.bar = 10;
sa *mySA = (sa *)&myS;
Then you can do this:
printf("I'm really a s.a.bar %d", (*mySA).bar);
Which will print out the appropriate value.
So now you can do:
(*mySA).bar = 22;
printf("%d", myS.b.bar);
You aren't really saving that much typing though.

Resources