2

I know that typedef'ing allows you to refer to a struct without using the struct keyword. However, with this:

typedef struct SYSTEM SYSTEM;

I've seen this typedef in a C API, but struct SYSTEM has not been defined previously.

In fact, a .c file containing only that line will compile by itself.

What does the compiler think SYSTEM (or struct SYSTEM) actually is?

Many thanks!

haccks
  • 104,019
  • 25
  • 176
  • 264
James
  • 1,430
  • 4
  • 20
  • 27
  • 1
    possible duplicate of [What is the effect of typedef'ing a struct to itself?](http://stackoverflow.com/questions/17515787/what-is-the-effect-of-typedefing-a-struct-to-itself) –  Jul 07 '13 at 20:17
  • ***You asked this question 18 minutes ago.*** It has been closed. Why are you reposting it, seriously? –  Jul 07 '13 at 20:18
  • 3
    @H2CO3: it's because he updated the question later and nobody answered that question... the updated question isn't a duplicate, and it shouldn't have been closed. and because there's no answer there this one shouldn't be closed as a duplicate either. oh well, it's complicated. – Karoly Horvath Jul 07 '13 at 20:29
  • 1
    @haccks one should take time before to vote for close question and down vote. – Grijesh Chauhan Jul 07 '13 at 20:37
  • @Grijesh; I did't vote down bro....and also I have not yet gained privilege to close questions :) – haccks Jul 07 '13 at 20:39
  • 1
    @haccks I asked you so that you can support my comment ;) , sorry misinterpreted – Grijesh Chauhan Jul 07 '13 at 20:44
  • @GrijeshChauhan; :D, very smart. Yes you are right, one should take time to down vote. – haccks Jul 07 '13 at 20:47

3 Answers3

5

The struct doesn't need to be defined. It only needs to be declared. The typedef declaration you present subsumes the declaration of struct SYSTEM.

So it's equivalent to:

struct SYSTEM;

typedef struct SYSTEM SYSTEM;

Thanks to this typedef, SYSTEM now names an incomplete type, so you can use it like SYSTEM * in interface definitions, without needing to expose the actual definition of the struct, which can be kept private:

public_header.h:

typedef struct SYSTEM SYSTEM;

SYSTEM * create_system();

int do_useful_thing_with(SYSTEM * system, int count, void * addr);

void destroy_system(SYSTEM * system);

private_impl.c:

#include <public_header.h>

struct SYSTEM { int a; char b[12]; float q; void * next; };

SYSTEM * create_system()
{ 
    SYSTEM * p = malloc(sizeof *p);
    if (p) { p->a = 2; p->q = 1.5; }
    return p;
}

void destroy_system(SYSTEM * system)
{
    free(system);
}

// etc.
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Thanks! So presumably the API programmers have defined this somewhere on the API-side of the interface? – James Jul 07 '13 at 20:14
  • @James: It's not empty. It's undefined. An empty struct is a defined struct like `struct Foo {};`. I added an explanation; you can use it as an incomplete type. – Kerrek SB Jul 07 '13 at 20:15
  • 1
    The purpose of being allowed to reference undefined structs is so that you can create pointers to that struct - perhaps from within that struct (this is most useful for declaring linked-lists, for example). – PP. Jul 07 '13 at 20:16
0

This is a typical C construct, as opposed to C++ and Java etc, that directly define types in the global namespace. C structs cannot be accessed by their name only, so the typedef is needed to be able to call a SYSTEM just SYSTEM.

struct SYSTEM {
  ...
};
struct SYSTEM foo;   //legal
SYSTEM bar;   //illegal
typedef struct SYSTEM SYSTEM;   //give it a global name
SYSTEM baz;   //now it's legal
cmaster - reinstate monica
  • 38,891
  • 9
  • 62
  • 106
-1

I'd say this is generally ill-advised behaviour but the gist is:

typedef type name

..where here the type is struct SYSTEM and the name assigned is SYSTEM.

Usually one would give a different name to the typedef than the type the typedef is derived from. Hence the low opinion many code maintainers might have to this kind of behaviour.

PP.
  • 10,764
  • 7
  • 45
  • 59
  • It is good if you use it right, it is bad if you abuse it. Good usage is usually precisely what the OP asked about (getting rid of unnecessary `struct` clutter), bad usage is precisely what you are talking about (giving arbitrary names to stuff already named). – cmaster - reinstate monica Jul 07 '13 at 20:23
  • 1
    Calling `struct` "clutter" is a gross misunderstanding of the type system in C and/or pure laziness. – PP. Jul 08 '13 at 07:11
  • *Usually one would give a different name to the typedef than the type the typedef is derived from.* Um, no. `typedef struct NAME NAME` is an extremely common idiom in older C code. It's DIY syntactic sugar to avoid having to type "struct" over and over. Nothing wrong with it. – dodgethesteamroller Jul 08 '13 at 14:26