Page 1 of 2

C linked list

Posted: Fri Jan 05, 2007 4:31 pm
by smbogan
This is a rather n00bish C question, but I generally program in C++. When you want to make a linked list with C, my compiler (DJGPP) won't allow me to do the following:

typedef struct
{
int somedata;
testStruct * next;
} testStruct;

Anyone know how to do this? I looked online, but only found C code which looks exactly like this...Currently I'm just calling them void *'s then casting them...which I really don't like.

Re: C linked list

Posted: Fri Jan 05, 2007 4:54 pm
by Candy
smbogan wrote:This is a rather n00bish C question, but I generally program in C++. When you want to make a linked list with C, my compiler (DJGPP) won't allow me to do the following:

typedef struct
{
int somedata;
testStruct * next;
} testStruct;

Anyone know how to do this? I looked online, but only found C code which looks exactly like this...Currently I'm just calling them void *'s then casting them...which I really don't like.

Code: Select all

typedef struct testStruct
{
   int somedata;
   struct testStruct * next;
} testStruct;
Should work. The name testStruct isn't defined until after the struct definition, while the name "struct testStruct" is at the start. You can also choose a slightly cleaner definition:

Code: Select all

struct testStruct
{
   int somedata;
   struct testStruct * next;
};
typedef struct testStruct testStruct;

Posted: Sat Jan 06, 2007 3:01 pm
by Solar
...or you could do it even cleaner and not re-use the name of the struct (which gives me the creeps, style-wise). 8)

Posted: Sat Jan 06, 2007 11:46 pm
by carbonBased
Solar wrote:...or you could do it even cleaner and not re-use the name of the struct (which gives me the creeps, style-wise). 8)
Agreed. Any good coding style should differentiate the struct name from its typedef counterpart. I use:

Code: Select all

struct _TestStruct
{
   int somedata;
   struct _TestStruct *next;
} TestStruct;
Although I understand why some find underscores ugly, and may not like *my* specific approach.

I'd also recommend generalizing your lists and making the payload a void* pointer (which I generally typedef to a 'Pointer' type :)). This way the same routines can be used to create lists of ints, strings, objects, etc.

You also could, conceivably, make lists of different typed objects -- but this would be bad :) And, obv. is the downfall of void pointers.

--Jeff

Posted: Sun Jan 07, 2007 6:35 am
by Seven11
I don't agree with you and I don't think that typedef should be sepparated from the struct definition (unless it has to)... but that's my personal coding style...

Posted: Sun Jan 07, 2007 7:36 am
by Solar
Actually, my coding style doesn't use typedef's at all except for function pointers. ;-)

Posted: Sun Jan 07, 2007 7:45 am
by Brynet-Inc
I ran into such a thing when attempting to port a friends application to OpenBSD, Such structures are annoying and confusing.

Posted: Sun Jan 07, 2007 1:19 pm
by Candy
Solar wrote:Actually, my coding style doesn't use typedef's at all except for function pointers. ;-)
Can say that my coding style uses lots and lots of typedefs, but none for structs or particular pointers and such. Functions pointers occasionally, when the code starts to look ugly. Most typedefs are just renames for common types to be named by their application so you don't swap f.ex. a physical page address with a virtual page address - that is, that the compiler warns you about that.

Posted: Sun Jan 07, 2007 3:14 pm
by smbogan
How do you not use typedefs for structs in C? I know how to do it in C++, but the same code for structs in C++ doesn't compile in DJGPP...but, the approaches he gave me worked fine.

Personally, my coding style doesn't really care, so long as it works...

Posted: Sun Jan 07, 2007 3:46 pm
by carbonBased
Seven11 wrote:I don't agree with you and I don't think that typedef should be sepparated from the struct definition (unless it has to)... but that's my personal coding style...
Any reasoning behind it? Just curious.

I have a lot of opaque pointers in my OS. The "user" would be using an opaque typedef to a pointer to a struct. The kernel itself, of course, uses the actual struct which is defined privately outside the header.

Because of this, I find it a convenient to have notation to differentiate the two.
Solar wrote: Actually, my coding style doesn't use typedef's at all except for function pointers. Wink
How do you handle portability of types? Different platforms/compilers can have alternative bit sizes per data types, of course. I find a typedef the most convenient way to handle this.

--Jeff

Posted: Sun Jan 07, 2007 4:16 pm
by Combuster
carbonBased wrote:
Solar wrote: Actually, my coding style doesn't use typedef's at all except for function pointers. Wink
How do you handle portability of types? Different platforms/compilers can have alternative bit sizes per data types, of course. I find a typedef the most convenient way to handle this.
I think when he meant coding style, he meant anything beyond that what is required.

Otherwise........
Solar's PDCLIB wrote:

Code: Select all

typedef signed int         _PDCLIB_int32_t;
typedef unsigned int       _PDCLIB_uint32_t;

Code: Select all

typedef struct
{
    int position;
    int parse_state;
} _PDCLIB_fpos_t;
:twisted:

I personally use the typedef struct X {...} X; style. It works and people tend to think "structure!" when they see 'typedef struct'. I personally have to think twice when i come across a struct without typedef...
Most importantly, it works :)

Posted: Sun Jan 07, 2007 7:14 pm
by elderK
could go :

typedef struct def_bla bla;

struct def_bla {
bla* next;
...whatever else...
};

bla* head;

Posted: Mon Jan 08, 2007 1:20 am
by Solar
Combuster wrote:I think when he meant coding style, he meant anything beyond that what is required.
ACK.
Otherwise........
Solar's PDCLIB wrote:

Code: Select all

typedef signed int         _PDCLIB_int32_t;
typedef unsigned int       _PDCLIB_uint32_t;

Code: Select all

typedef struct
{
    int position;
    int parse_state;
} _PDCLIB_fpos_t;
:twisted:
The first two allow me to do the required typedefs (e.g., int32_t) in <stdint.h> to a configurable type (_PDCLIB_int32_t), i.e. keeping the configuration in one internal header, instead of spreading it out across all the standard headers.

The latter is a platform dependency; a system could handle file position with something other but a struct, and the typedef allows for that.

So, it's like you said - my code style is not to use typedefs, but I don't let my code style influence my design decisions... much. 8)

Posted: Tue Jan 09, 2007 3:32 am
by Jules
smbogan wrote:How do you not use typedefs for structs in C? I know how to do it in C++, but the same code for structs in C++ doesn't compile in DJGPP...

Code: Select all

struct MyLinkedList
{
   int data;
   struct MyLinkedList * next;
};

...

struct MyLinkedList * head;

...
The only difference from C++ is that you need to precede references to the structure's name with the keywork 'struct'. IMO, this is a *lot* cleaner than using typedefs all the time.

Posted: Tue Jan 09, 2007 5:29 am
by Solar
They are "somewhat" OK for structs, but generally typedefs quickly start obfuscating what type a variable really is.

That can be bad enough if you have a type vector<Value>, which is typedef'ed to TableRow or ObjectList or ItemArray in various contexts, so you have to trace back through various headers to find out what members the type actually has.

It gets positively dreadful when people start typedef'ing pointer types, use standard names for non-standard constructs, or name containers after types they are not (maps that are named vector or vice versa, for example).