Re: [Q] superfluous ids in self-referential typedef struct

From: Dave Thompson (david.thompson1_at_worldnet.att.net)
Date: 12/13/04


Date: Mon, 13 Dec 2004 06:38:15 GMT

On Fri, 3 Dec 2004 21:48:06 +0000, Chris Croughton
<chris@keristor.net> wrote:

> On Fri, 3 Dec 2004 18:27:37 +0000 (UTC), J Krugman
> <jkrugman345@yahbitoo.com> wrote:
>
> > My compiler complains if I do something like this
> >
> > typedef struct {
> > node *next;
> > } node;
>
> With good reason, you're asking it to use an identifier before it knows
> anything about the identifier. C compilers are not prophets, they

Although this is really a self-fulfulling prophecy. The language was
defined to be one-pass parseable to simplify the initial compiler(s),
so as a result all compilers now can be and typically are. You can
design a language that doesn't do this and successfully compile it --
the case in point is PL/I. But there doesn't seem to be any great
benefit in doing so, and clearly not very strong demand.

> pretty much work in a linear fashion. Even if it did do some kind of
> lookahead you would get into trouble with mutually referencing structs
> (A has a pointer to B and B has a pointer to A).
>
With a syntax that unambiguously identifies type names used as targets
like Pascal, or at all like Fortran, you don't need type declaration
first; Ada could do the same, but chose not to. Or with untyped
pointers like PL/I the issue doesn't even arise.

> > but it's OK with
> >
> > typedef struct superfluous_identifier {
> > superfluous_identifier *next;
> > } node;
>
> Yup, except that the identifier isn't superfluous to the language.
>
> > I hate that superfluous_identifier. Is there any way to avoid it?
>
> (a) Use C++, where typedefs share the same name space with structs and

Using C++ only avoids the keyword 'struct', not the 'superfluous
identifier'. And they don't exactly _share_ the namespace, rather tags
are available as typenames. In both languages typedefs share a
namespace with objects and functions and it is still legal in C++,
although arguably more confusing, to have an object or function x and
also a struct/class and/or union and/or enum x in the same scope.

> unions. This can cause other problems, for instance the construct
>
> typedef struct node node;
> struct node
> {
> node *next;
> };
>
> is invalid in C++ ('node' is delcared twice), so in header files which

No, it's not. Unlike C, C++ allows "benign" redeclarations of types,
that is redeclaration to the "same" type. Perhaps partly to allow this
idiom; I'd have to try to look up in D&E to check. Possibly this
wasn't true in very early C++ (or CwC?); I don't recall trying then.

Much as both C and C++ allow "benign" re-#define-ition of a macro,
albeit C++ attempts to discourage all macros to a significant extent.

> have to be includable by both languages the identifiers must be
> different (I generally use _s on the end for the struct name and _t or T
> for the type, but coding standards vary and there is no One True Naming
> Convention).
>
<rest snipped>

- David.Thompson1 at worldnet.att.net



Relevant Pages

  • Re: Question on Pointers
    ... Regarding some rather old wording describing a language that is ... was perfectly legal to assign an 'int' value to a pointer), ... struct A { ... To make this compile on today's compilers, ...
    (comp.lang.c)
  • Re: [Q] superfluous ids in self-referential typedef struct
    ... you're asking it to use an identifier before it knows ... C compilers are not prophets, ... > typedef struct superfluous_identifier { ...
    (comp.lang.c)
  • Re: A C Adventure: your comments are welcome
    ... struct bar * ref;}; ... Compilers ... The newline is added by formatting. ... hasn't been tested, yet, but it makes a rope node with at most a left ...
    (comp.lang.c)
  • Re: C# Plugin system - same interface in two different assemblies...
    ... easy to see why the .NET designers went with the tried and true approach of just checking a unique identifier for each type. ... This is essentially what you achieve with COM by saying "yes, I implement this interface with this UID too", but then you want it by structural compatibility, not an agreed-upon UID. ... I'm not sure what you mean, as GCC, Intel, and Microsoft's compilers all produce compatible plugins for several products in our product suite. ... As long as you don't get subtle with multiple inheritance, method pointers or exceptions, those compilers will all produce the same low-level binary stuff to make sure it'll work with the other compilers. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Any way to use fortran90 module in C?
    ... one requirement on a struct, and that is a pointer to the struct works as a pointer to the first element. ... Compilers I know of use padding but not rearranging, though I believe rearranging is allowed. ... the first member, ...
    (comp.lang.fortran)