Re: Porting from visual C to gcc problem



On Sun, 21 Aug 2005 05:46:20 -0000, Barry Schwarz <schwarzb@xxxxxxxxx>
wrote in comp.lang.c.moderated:

> On Sat, 20 Aug 2005 04:18:26 -0000, Jack Klein <jackklein@xxxxxxxxxxx>
> wrote:
>
> >On Fri, 19 Aug 2005 22:05:48 -0000, Gustin.Kiffney@xxxxxxxxx wrote in
> >comp.lang.c.moderated:
> >
> >I will add some detail interspersed in your code.
> >
> >> This code is in a file dnis.h:
> >>
> >> typedef DNIS_ERROR (*DNIS_TIMER_CALLBACK) (struct DNIS_TIMER_CB
> >> *timerCB);
> >
> >The declaration above defines the identifier 'DNIS_TIMER_CALLBACK' as
> >an alias for "a pointer to a function that returns an object of type
> >'DNIS_ERROR', and takes a single parameter that is a pointer to a
> >'struct DNIS_TIMER_CS'.
> >
> >Somewhere before this, the compiler must have come across the typedef
> >or macro defining 'DNIS_ERROR', otherwise you would have gotten
> >another error first.
> >
> >> typedef struct DNIS_TIMER_CB
> >> {
> >> UTIL_LIST_ENTRY listEntry;
> >> DNIS_SIGNATURE_TYPE signature;
> >> DNIS_TIMER_ID timerID;
> >> DNIS_TIME timeout;
> >> DNIS_TIME expiration;
> >> DNIS_TIMER_CALLBACK callBack;
> >> ULONG context;
> >> } DNIS_TIMER_CB;
> >
> >Now here, after that typedef, is a typedef that includes a definition
> >of a structure type named 'struct DNS_TIMER_CB'.
> >
> >> gcc doesn't like this.
> >>
> >> When the compiler hits this definition, it says
> >> ../Hdr/dnis.h:68: warning: `struct DNIS_TIMER_CB' declared inside
> >> parameter list
> >> ../Hdr/dnis.h:68: warning: its scope is only this definition or
> >> declaration, which is probably not what you want
> >
> >gcc is correct here, and Visual C++ is wrong. But the gcc error
> >message might have been a little clearer.
> >
> >C is a scoped language, and one of the scopes is "prototype scope".
> >That basically means that there is a scope that begins at the '(' in a
> >function declaration, and ends at the ')'. Any types or identifiers
> >defined inside the '(' and the ')' go out of scope at the end. The
> >only exception to this is when the function declaration also defines
> >the body of the function, then the scope lasts to through the body to
> >the closing '}'.
> >
> >That is why you can have this in a C file:
> >
> >int func(int a, int b);
> >int func(int c, int d);
> >
> >int func(int x, int y)
> >{
> > return x + y;
> >}
> >
> >There are three declarations of 'func', but there is no conflict with
> >different names for the parameters. That is because the names in the
> >two prototypes are forgotten as soon as the ';' closes the declaration
> >without a body.
> >
> >So the typedef for 'DNIS_TIMER_CALLBACK' includes a declaration of an
> >incomplete type 'struct DNIS_TIMER_CB' and says the function accepts a
> >pointer to this type. Well and good. But if the compiler has not
> >already seen a definition of 'struct DNIS_TIMER_CB', this declaration
> >has prototype scope, and ends at the ';'. In particular, it is a
> >completely different type and completely unrelated to anything defined
> >in an outer scope afterwards.
> >
> >> and all references to DNIS_TIMER_CB explode with, for example,
> >>
> >> ../Hdr/switch.h:39: error: syntax error before "DNIS_TIMER_CB"
> >> ../Hdr/switch.h:39: warning: no semicolon at end of struct or union
> >>
> >> I am trying to get this code to run under Unix/Linux and I'm not very
> >> experienced in C. I'm not at all sure what this
> >> typedef DNIS_ERROR (*DNIS_TIMER_CALLBACK) (struct DNIS_TIMER_CB
> >> timerCB);
> >>
> >> is supposed to mean or do; it looks frankly like a mess to me. Anyone
> >> know what the programmer meant by this? Any way to make this portable
> >> to gcc/Linux?
> >
> >The programmer who wrote this depended on non-standard behavior by his
> >compiler. It might be a VC++ bug, or a deliberate Microsoft
> >extension. Either way, your experience with gcc shows the dangers in
> >depending on non-standard extensions, especially when you try to port
> >the code.
>
> You were right up to this point.
>
> >
> >In any case, the fix is quite simple. Move the complete definition
> >with typedef of the 'DNIS_TIMER_CB' structure above the typedef of the
> >'DNIS_TIMER_CALLBACK' function pointer. That's all it takes. Then
> >when the compiler sees the 'struct DNIS_TIMER_CB *timerCB', it will
> >not take it as a new definition of a new type, because it already has
> >a definition of the structure type in scope.
>
> This won't work because the definition of the structure requires the
> typedef for DNIS_TIMER_CALLBACK in order for the 6th member of the
> structure to be properly defined. I think the real answer is to
> insert a simple
> struct DNIS_TIMER_CB;
> before the typedef for DNIS_TIMER_CALLBACK.

Thanks for catching what I missed. I didn't compile this because I
don't have a version of gcc installed at the time. My mistake!

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
--
comp.lang.c.moderated - moderation address: clcm@xxxxxxxxxxxx -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.
.



Relevant Pages

  • compiling kernel
    ... scripts/kconfig/qconf.h:51: error: `e' was not declared in this scope ... scripts/kconfig/qconf.h:73: error: `int updateList' redeclared as different ... scripts/kconfig/qconf.h:8: error: forward declaration of `class ConfigList' ... ConfigLineEdit' ...
    (alt.os.linux.suse)
  • Re: formal parameter 1 different from declaration?
    ... Here is the typedef one: ... typedef LR (HWND, long, int, int); ... struct tagWnd; // forward declaration ... takes a struct tagHwnd and the other takes a long. ...
    (microsoft.public.vc.language)
  • Re: typedef function pointer
    ... the semantics for typedef is: ... That's the syntax, not the semantics. ... to be an array of 20 ints, the declaration is ... to a function taking to int arguments and returning it, ...
    (comp.lang.c)
  • Re: typedef with function pointers
    ... Forget about the typedef for a moment, ... you say "*x is an int, hence x is a pointer to int." ... the other elements of the declaration depends on the way ... and function pointers got answered. ...
    (comp.lang.c)
  • Re: syntax errror
    ... >>> int maxGrey' ... >> declaration of maxGrey. ... typedef double; ... struct some_tag_name { ...
    (comp.lang.c)