why function like macro doesn't work here?

B

baumann@pan

hi all,

i defined a macro like the below


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

then in a function , i wrote

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

but the compiler complains
main.c
e:\project\scanap\main.c(11) : error C2059: syntax error : 'do'
e:\project\scanap\main.c(11) : error C2065: 'ws_data' : undeclared
identifier
e:\project\scanap\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
 
K

Keith Thompson

baumann@pan said:
hi all,

i defined a macro like the below


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

then in a function , i wrote

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

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


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

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.
 
B

baumann@pan

Keith said:
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.


is there the way to solute it by macro?
 
J

John Bode

baumann@pan said:
hi all,

i defined a macro like the below


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

then in a function , i wrote

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

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;WSAStartup(0x0202,&ws_data);}while(0))

Hence the following:
but the compiler complains
main.c
e:\project\scanap\main.c(11) : error C2059: syntax error : 'do'
e:\project\scanap\main.c(11) : error C2065: 'ws_data' : undeclared
identifier
e:\project\scanap\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.

Don't do it as a macro. That's about the only help I can offer.
 
M

Me

baumann@pan said:
#define initSock() \
do{\
WSADATA ws_data;\
WSAStartup(0x0202,&ws_data);\
}while(0)

then in a function , i wrote

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

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


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

"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(0x0202, &(WSADATA){})
 
K

Kenneth Brody

baumann@pan said:
hi all,

i defined a macro like the below

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

then in a function , i wrote

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

but the compiler complains
main.c
e:\project\scanap\main.c(11) : error C2059: syntax error : 'do'
e:\project\scanap\main.c(11) : error C2065: 'ws_data' : undeclared
identifier
e:\project\scanap\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.

If I declare initSock() as a function:

void initSock()
{
do{
WSDATA ws_data;
WSAStartup(0x0202,&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:[email protected]>
 
D

Dave Thompson

On 8 Jul 2005 13:01:46 -0700, "Me" <[email protected]>
wrote:

"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

Actually, that yields scalar = not void and not struct or union;
arithmetic or pointer is OK, or array which decays to pointer.
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)
...
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 */
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(0x0202, &(WSADATA){})

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

- David.Thompson1 at worldnet.att.net
 
S

Sensei

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

then in a function , i wrote

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

Wrong.

Why don't you use

inline int initSock()
{
....
}
if i change the macro to static function, it's ok.

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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top