Macros within function-like macros?

  • Thread starter Anthony de Almeida Lopes
  • Start date
A

Anthony de Almeida Lopes

Hello,

I am wondering why it is not possible to have a function-like macro like
the following:

#define __nothread(name) do { \
#ifdef _PTHREAD_H \
#warning "name is not a thread safe function" \
} while (0)

I get the error "test.h:2:2: '#' is not followed by a macro parameter"

Actually, the exact goal is to have a prototypes such
as:

__nothread int function(void);

which would generate a warning when compiled with _PTHREAD_H or
_REENTRANT defined.

Is this possible?
I am curious how __attribute__ works internally. Right now I'm looking
through the gcc-3.3.4 source; so, hopefully I'll find the answer to that.

Thanks,
-Anthony
 
A

August Karlstrom

Anthony said:
Hello,

I am wondering why it is not possible to have a function-like macro like
the following:

#define __nothread(name) do { \
#ifdef _PTHREAD_H \
#warning "name is not a thread safe function" \
} while (0)

Why not define an inline function instead?

inline void __nothread(const char *name)
{
...
}


August
 
F

Flash Gordon

Using names starting with an underscore is a really bad idea, many of
them are reserved and it's generally not worth remembering which ones
can be used and when. In particular, ALL names starting with two
underscores are always reserved for any use.

You can't have one preprocessor directive inside another, that is why
you can't do this.
Why not define an inline function instead?

Possibly the OP is not using a C99 compiler since there are not many of
them around. inline is not part of the more commonly implemented C89
standard.
inline void __nothread(const char *name)

Again, avoid identifiers starting with underscores.
 
E

Eric Sosman

Anthony said:
Hello,

I am wondering why it is not possible to have a function-like macro like
the following:

#define __nothread(name) do { \
#ifdef _PTHREAD_H \
#warning "name is not a thread safe function" \
} while (0)

I get the error "test.h:2:2: '#' is not followed by a macro parameter"

Because "The resulting [...] token sequence is not processed
as a preprocessing directive even if it resembles one [...]"
(ISO/IEC 9899:199, section 6.10.3.4 paragraph 3). In other words,
because a macro expansion cannot produce a preprocessing directive.

It might also be noted that C has no #warning directive. The
line is legal, but is a "non-directive" (section 6.1, paragraph 1).
Actually, the exact goal is to have a prototypes such
as:

__nothread int function(void);

which would generate a warning when compiled with _PTHREAD_H or
_REENTRANT defined.

Is this possible?

You could do something like this (but see Flash Gordon's
response about reserved identifiers):

#if defined _PTHREAD_H || defined _REENTRANT
#define __nothread >>> "Not thread-safe!" <<<
#else
#define __nothread /* empty */
#endif
__nothread int function(void);

.... but I have a hunch you want something a little different
from what you've described. My guess is that you don't want an
error when the declaration is compiled with the undesired macros
defined, but when code compiled with the unwelcome macros calls
the declared function. The best I can think of for that problem
is something along the lines of

int function(void);
double trouble(int boil);
...
#if defined _PTHREAD_H || defined _REENTRANT
#define function >>> "Not thread-safe!" <<<
#define trouble >>> "Not thread-safe!" <<<
...
#endif
I am curious how __attribute__ works internally. Right now I'm looking
through the gcc-3.3.4 source; so, hopefully I'll find the answer to that.

__attribute__ is not part of C. Ask in a gnu forum.
 
S

Sandeep

can we have an inline function in Standard C ?

August said:
Why not define an inline function instead?

inline void __nothread(const char *name)
{
...
}


August
 
G

Giannis Papadopoulos

Giannis said:
Yes, if your compiler supports the ISO C99 standard. And please do not
post.

please do not top post... I knew I forgot something...
 
P

pemo

Keith Thompson said:
It's also a common extension in pre-C99 compilers.

But it's still only a 'hint'.

This 'macro function' swap will *always* be inlined

#define MXORSwap(x, y) \
if((x) != (y)) \
{\
(*x) ^= (*y);\
(*y) ^= (*x);\
(*x) ^= (*y);\
}

whereas this 'real function' version may not be, plus it's not 'as generic'
of course.

inline void FXORSwap(int * x, int * y)
{
if(x != y)
{
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
}

int main(void)
{
int a; int b;

a = 42; b = 24;

MXORSwap(&a, &b);

FXORSwap(&a, &b);

...
}
 
K

Keith Thompson

pemo said:
But it's still only a 'hint'.

This 'macro function' swap will *always* be inlined

#define MXORSwap(x, y) \
if((x) != (y)) \
{\
(*x) ^= (*y);\
(*y) ^= (*x);\
(*x) ^= (*y);\
}

whereas this 'real function' version may not be, plus it's not 'as generic'
of course.

inline void FXORSwap(int * x, int * y)
{
if(x != y)
{
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
}
[snip]

Please read question 10.3 in the C FAQ, <http://www.c-faq.com/>.
 
P

pemo

Keith Thompson said:
pemo said:
But it's still only a 'hint'.

This 'macro function' swap will *always* be inlined

#define MXORSwap(x, y) \
if((x) != (y)) \
{\
(*x) ^= (*y);\
(*y) ^= (*x);\
(*x) ^= (*y);\
}

whereas this 'real function' version may not be, plus it's not 'as
generic'
of course.

inline void FXORSwap(int * x, int * y)
{
if(x != y)
{
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
}
[snip]

Please read question 10.3 in the C FAQ, <http://www.c-faq.com/>.

Yes, I've seen that, and, hmmm, maybe I should have used another example to
make 'the point' that I was attempting.
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top