Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #21868

Re: interpret this code?

From James Kuyper <jameskuyper@verizon.net>
Newsgroups comp.lang.c
Subject Re: interpret this code?
Date 2012-06-05 09:19 -0400
Organization A noiseless patient Spider
Message-ID <jql115$4v4$1@dont-email.me> (permalink)
References <30urs79vrgihohjaoca4g3bj1kfbcqa5jk@4ax.com>

Show all headers | View raw


On 06/05/2012 08:26 AM, George wrote:
> I'm working on an old (comment-free) program, and finding some of the
> code is above my pay grade.  I'd appreciate insight into what's going on
> with the segment below.
> 
> -----------------
>   #define SCRN_LIST \
>      SCRN(Null) \
>      SCRN(RYG) \
>      SCRN(Fr00) \
>      SCRN(LastN) \
>      SCRN(DateTime) \
> 
>   #define INIT_LIST \
>      INIT(Default) \
>      INIT(LastN) \
>      INIT(EvtLog) \
>      INIT(EvtLogDetail) \
> 
>   typedef void (*VOID_FNC)(void);
>    
>   #define SCRN(symm) (const VOID_FNC)symm##ScrnFnc,
>   #define INIT(symm) (const VOID_FNC)symm##InitFnc,
>     const VOID_FNC ScrnFnc[] = {
>        SCRN_LIST
>        INIT_LIST
>     };
>   #undef  SCRN
>   #undef  INIT
> 
>     // typical fnc
>      
>   void
>   NullScrnFnc(void) { ... }
> -----------------
> 
> I think the final result wants to be ...
>   const void (*ScrnFnc[])() = { 
>     NullScrnFnc, 
>     RYGScrnFnc, 
>     ...
>     DefaultInitFnc,
>     LastNInitFnc,
>     ...
>   };
>   
> Even assuming that's correct, I don't see how it gets there.  I see that
> SCRN_LIST/INIT_LIST will cause ea of their listed arguments (Null, RYG,
> etc) to instantiate the 'SCRN'/'INIT' macros in the ScrnFnc[]
> declaration,  But, ISTM, this would create something like (eg) ...
>   void (*NullFnc)()

The expansion is actually

	(const VOID_FUNC)NullScrnFnc

The equivalent without use of typedefs would be:

	(void(*)(void) const)NullScrnFnc

In other words, it is an expression declaring that NullScrnFnc is an
object of type (void(*)(void) const). A typedef is not simply a macro,
which is why the const needs to be moved to the end of the cast. In an
expression like "const int i", the keyword const modifies 'i'; the same
is true in "const VOID_FUNC NullScrnFnc". However, if we were to write
"const void(*)(void) NullScrnFnc", then the 'const' would (with
undefined behavior - 6.7.3p9) modify the return type from the function.
You need to move the 'const' to the end of the type specification for it
to have the same meaning as it has in 'const VOID_FUNC'.

> Bonus points: I don't know how to 'read' the VOID_FNC typedef.  I think
> that's a standard construct (ptr to void fnc?), but the logic of it
> eludes me.

The way to read a typedef is to first interpret it as an ordinary
declaration, without the typedef. In this case, that would give us:

	void (*VOID_FNC)(void);

What this would mean is that (*VOID_FUNC)() would be an expression of
type void. The second pair of parentheses mean that (*VOID_FUNC) is a
function. The second 'void' means that the function does not take any
arguments. The '*' would indicate that VOID_FUNC is a pointer. Put that
all together, and it would mean that VOID_FUNC is a pointer to a
function taking no arguments and returning nothing.

The effect of prefixing the declaration with "typedef" is that instead
of VOID_FNC being the identifier for an object of that type, it's an
alias for the type of such an object.
-- 
James Kuyper

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

interpret this code? George <gbeccles@verizon.net> - 2012-06-05 08:26 -0400
  Re: interpret this code? James Kuyper <jameskuyper@verizon.net> - 2012-06-05 09:19 -0400
    Re: interpret this code? Nick Bowler <nbowler@draconx.ca> - 2012-06-05 15:55 +0000
      Re: interpret this code? James Kuyper <jameskuyper@verizon.net> - 2012-06-05 12:05 -0400
  Re: interpret this code? "BartC" <bc@freeuk.com> - 2012-06-05 14:42 +0100
    Re: interpret this code? Noob <root@127.0.0.1> - 2012-06-05 16:19 +0200
  Re: interpret this code? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-05 14:43 +0100
  Re: interpret this code? Noob <root@127.0.0.1> - 2012-06-05 16:22 +0200
  Re: interpret this code? George <gbeccles@verizon.net> - 2012-06-05 22:50 -0400

csiph-web