why function like macro doesn't work here?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • baumann@pan

    #1

    why function like macro doesn't work here?

    hi all,

    i defined a macro like the below


    #define initSock() \
    do{\
    WSADATA ws_data;\
    WSAStartup(0x02 02,&ws_data);\
    }while(0)

    then in a function , i wrote

    if(!initSock())
    {
    .....
    }

    but the compiler complains
    main.c
    e:\project\scan ap\main.c(11) : error C2059: syntax error : 'do'
    e:\project\scan ap\main.c(11) : error C2065: 'ws_data' : undeclared
    identifier
    e:\project\scan ap\main.c(11) : warning C4133: 'function' : incompatible
    types - from 'int *' to 'struct WSAData *'


    if i change the macro to static function, it's ok.


    any help would be appreciated. thanks.

    bauman@Pan

  • Keith Thompson

    #2
    Re: why function like macro doesn't work here?

    "baumann@pa n" <asmboozer@hotm ail.com> writes:[color=blue]
    > hi all,
    >
    > i defined a macro like the below
    >
    >
    > #define initSock() \
    > do{\
    > WSADATA ws_data;\
    > WSAStartup(0x02 02,&ws_data);\
    > }while(0)
    >
    > then in a function , i wrote
    >
    > if(!initSock())
    > {
    > ....
    > }
    >
    > but the compiler complains
    > main.c
    > e:\project\scan ap\main.c(11) : error C2059: syntax error : 'do'
    > e:\project\scan ap\main.c(11) : error C2065: 'ws_data' : undeclared
    > identifier
    > e:\project\scan ap\main.c(11) : warning C4133: 'function' : incompatible
    > types - from 'int *' to 'struct WSAData *'
    >
    >
    > if i change the macro to static function, it's ok.[/color]

    The do { ... } while(0) macro definition trick lets you use a macro
    invocation as if it were a function call, but only in a statement
    context. It doesn't let you use it in an expression, because you
    can't have a loop in an expression.

    Even if it were allowed, your code probably wouldn't work. You're
    trying to use the value "returned" by initSock(), but it doesn't yield
    a value.

    --
    Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.

    Comment

    • baumann@pan

      #3
      Re: why function like macro doesn't work here?



      Keith Thompson wrote:[color=blue]
      > "baumann@pa n" <asmboozer@hotm ail.com> writes:[color=green]
      > > hi all,
      > >
      > > i defined a macro like the below
      > >
      > >
      > > #define initSock() \
      > > do{\
      > > WSADATA ws_data;\
      > > WSAStartup(0x02 02,&ws_data);\
      > > }while(0)
      > >
      > > then in a function , i wrote
      > >
      > > if(!initSock())
      > > {
      > > ....
      > > }
      > >
      > > but the compiler complains
      > > main.c
      > > e:\project\scan ap\main.c(11) : error C2059: syntax error : 'do'
      > > e:\project\scan ap\main.c(11) : error C2065: 'ws_data' : undeclared
      > > identifier
      > > e:\project\scan ap\main.c(11) : warning C4133: 'function' : incompatible
      > > types - from 'int *' to 'struct WSAData *'
      > >
      > >
      > > if i change the macro to static function, it's ok.[/color]
      >
      > The do { ... } while(0) macro definition trick lets you use a macro
      > invocation as if it were a function call, but only in a statement
      > context. It doesn't let you use it in an expression, because you
      > can't have a loop in an expression.
      >
      > Even if it were allowed, your code probably wouldn't work. You're
      > trying to use the value "returned" by initSock(), but it doesn't yield
      > a value.
      >
      > --
      > Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
      > San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
      > We must do something. This is something. Therefore, we must do this.[/color]


      is there the way to solute it by macro?

      Comment

      • Chris Dollin

        #4
        Re: why function like macro doesn't work here?

        baumann@pan wrote:
        [color=blue][color=green][color=darkred]
        >> >
        >> > i defined a macro like the below
        >> >
        >> >
        >> > #define initSock() \
        >> > do{\
        >> > WSADATA ws_data;\
        >> > WSAStartup(0x02 02,&ws_data);\
        >> > }while(0)
        >> >
        >> > then in a function , i wrote
        >> >
        >> > if(!initSock())[/color][/color][/color]
        [color=blue]
        > is there the way to solute it by macro?[/color]

        I don't think so; but why would you bother?

        --
        Chris "electric hedgehog" Dollin
        It's called *extreme* programming, not *stupid* programming.

        Comment

        • John Bode

          #5
          Re: why function like macro doesn't work here?



          baumann@pan wrote:[color=blue]
          > hi all,
          >
          > i defined a macro like the below
          >
          >
          > #define initSock() \
          > do{\
          > WSADATA ws_data;\
          > WSAStartup(0x02 02,&ws_data);\
          > }while(0)
          >
          > then in a function , i wrote
          >
          > if(!initSock())
          > {
          > ....
          > }
          >[/color]

          Whoa, hold on. Remeber that a macro is a text placeholder *only*;
          after preprocessing, the above statement gets expanded to

          if (!do{WSADATA ws_data;WSAStar tup(0x0202,&ws_ data);}while(0) )

          Hence the following:
          [color=blue]
          > but the compiler complains
          > main.c
          > e:\project\scan ap\main.c(11) : error C2059: syntax error : 'do'
          > e:\project\scan ap\main.c(11) : error C2065: 'ws_data' : undeclared
          > identifier
          > e:\project\scan ap\main.c(11) : warning C4133: 'function' : incompatible
          > types - from 'int *' to 'struct WSAData *'
          >
          >
          > if i change the macro to static function, it's ok.
          >
          >
          > any help would be appreciated. thanks.[/color]

          Don't do it as a macro. That's about the only help I can offer.
          [color=blue]
          >
          > bauman@Pan[/color]

          Comment

          • Me

            #6
            Re: why function like macro doesn't work here?

            baumann@pan wrote:[color=blue]
            > #define initSock() \
            > do{\
            > WSADATA ws_data;\
            > WSAStartup(0x02 02,&ws_data);\
            > }while(0)
            >
            > then in a function , i wrote
            >
            > if(!initSock())
            > {
            > ....
            > }
            >
            > but the compiler complains
            > main.c
            > e:\project\scan ap\main.c(11) : error C2059: syntax error : 'do'
            > e:\project\scan ap\main.c(11) : error C2065: 'ws_data' : undeclared
            > identifier
            > e:\project\scan ap\main.c(11) : warning C4133: 'function' : incompatible
            > types - from 'int *' to 'struct WSAData *'
            >
            >
            > if i change the macro to static function, it's ok.[/color]

            "if" wants an expression that returns non-void, you're passing a
            statement (minus the required semi-colon) to it. You have a few ways to
            convert this to an expression (I'm assuming the return of WSAStartup is
            the thing you want to test):

            1. rewrite this macro:
            #define initSock(v) ... v = WSAStartup ...

            some_t good;
            initSock(v);
            if (v)
            ...

            2. GNU C expression statement extension:
            basically replace the do with ( and replace the while(0) with ).

            3. rewrite it as a function:
            you can figure this out

            4. C99 compound literals:
            #define initSock() WSAStartup(0x02 02, &(WSADATA){} )

            Comment

            • Kenneth Brody

              #7
              Re: why function like macro doesn't work here?

              "baumann@pa n" wrote:[color=blue]
              >
              > hi all,
              >
              > i defined a macro like the below
              >
              > #define initSock() \
              > do{\
              > WSADATA ws_data;\
              > WSAStartup(0x02 02,&ws_data);\
              > }while(0)
              >
              > then in a function , i wrote
              >
              > if(!initSock())
              > {
              > ....
              > }
              >
              > but the compiler complains
              > main.c
              > e:\project\scan ap\main.c(11) : error C2059: syntax error : 'do'
              > e:\project\scan ap\main.c(11) : error C2065: 'ws_data' : undeclared
              > identifier
              > e:\project\scan ap\main.c(11) : warning C4133: 'function' : incompatible
              > types - from 'int *' to 'struct WSAData *'
              >
              > if i change the macro to static function, it's ok.
              >
              > any help would be appreciated. thanks.[/color]

              If I declare initSock() as a function:

              void initSock()
              {
              do{
              WSDATA ws_data;
              WSAStartup(0x02 02,&ws_data);
              }while(0);
              }

              my compiler complains here as well, telling me on the "if(!initSock() )"
              line:

              foo.c(20) : error C2171: '!' : illegal on operands of type 'void '
              foo.c(20) : error C2180: controlling expression has type 'void'
              foo.c(20) : error C2180: controlling expression has type 'void'

              Hint... what will be the result of expanding your macro?

              --
              +-------------------------+--------------------+-----------------------------+
              | Kenneth J. Brody | www.hvcomputer.com | |
              | kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer .h> |
              +-------------------------+--------------------+-----------------------------+
              Don't e-mail me at: <mailto:ThisIsA SpamTrap@gmail. com>

              Comment

              • Dave Thompson

                #8
                Re: why function like macro doesn't work here?

                On 8 Jul 2005 13:01:46 -0700, "Me" <anti_spam_emai l2003@yahoo.com >
                wrote:

                <snip>[color=blue]
                > "if" wants an expression that returns non-void, you're passing a
                > statement (minus the required semi-colon) to it. You have a few ways to[/color]

                Actually, that yields scalar = not void and not struct or union;
                arithmetic or pointer is OK, or array which decays to pointer.
                [color=blue]
                > convert this to an expression (I'm assuming the return of WSAStartup is
                > the thing you want to test):
                >
                > 1. rewrite this macro:
                > #define initSock(v) ... v = WSAStartup ...
                >
                > some_t good;
                > initSock(v);
                > if (v)
                > ...
                >[/color]
                initSock(good);
                if( good )

                except that actually WSAStartup returning 0 is good and nonzero is
                bad, so either
                #define initSock(ok) ... ok = WSAStartup (...) == 0; ...
                _Bool myok; initSock (myok); if( !myok ) /* error */

                or
                #define initSock(err) ... err = WSAStartup (...); ....
                int myerr; initSock (myerr); if( myerr /* != 0 */ ) /* error */
                [color=blue]
                > 2. GNU C expression statement extension:
                > basically replace the do with ( and replace the while(0) with ).
                >
                > 3. rewrite it as a function:
                > you can figure this out
                >
                > 4. C99 compound literals:
                > #define initSock() WSAStartup(0x02 02, &(WSADATA){} )[/color]

                or even in C90 ... WSAStartup (0x0202, malloc(sizeof(W SADATA))) ...
                leaving one fairly small memory leak per process.

                - David.Thompson1 at worldnet.att.ne t

                Comment

                • Sensei

                  #9
                  Re: why function like macro doesn't work here?

                  On 2005-07-07 21:27:51 -0500, "baumann@pa n" <asmboozer@hotm ail.com> said:
                  [color=blue]
                  > #define initSock() \
                  > do{\
                  > WSADATA ws_data;\
                  > WSAStartup(0x02 02,&ws_data);\
                  > }while(0)
                  >
                  > then in a function , i wrote
                  >
                  > if(!initSock())
                  > {
                  > ....
                  > }[/color]

                  Wrong.

                  Why don't you use

                  inline int initSock()
                  {
                  ....
                  }
                  [color=blue]
                  > if i change the macro to static function, it's ok.[/color]

                  I make it easy: think the #define statement as just as a
                  Search-and-Replace facility given by the compiler.

                  --
                  Sensei <senseiwa@tin.i t>

                  cd /pub
                  more beer

                  Comment

                  Working...