Re: Porting from visual C to gcc problem



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.



<<Remove the del for email>>
--
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: Porting from visual C to gcc problem
    ... the compiler must have come across the typedef ... >>function declaration, ... then the scope lasts to through the body to ... >>int func; ...
    (comp.lang.c.moderated)
  • 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)