C tricky problem or gcc preprocessor bug ???

S

Subra

Hi,

Compilation of the below code fails
cat test.c

#define a this1, /* Comma is intentional line 1*/

#define fun( x, y, z) y*x*z/*line 2*/

char this1,b,c;/*line 3*/
int main()/*line 4*/
{
fun(b, a c); /*Comma is leftout intetionaly line 5*/
}/*line 6*/

with errors as below
gcc test.c
test.c:8:15: macro "fun" requires 3 arguments, but only 2 given
test.c: In function `main':
test.c:8: error: `fun' undeclared (first use in this function)
test.c:8: error: (Each undeclared identifier is reported only once
test.c:8: error: for each function it appears in.)


If I just change line 1 and line 5 as below it works obviously.
I want to compile the original above code as it is just a snippet of
my project ! Please help.

"#define a this1," to "#define a this1"
"fun(b, a c);" to "fun(b, a, c);" (as below)then it works fine.
cat test.c
#define a this1, /*line 1*/

#define fun( x, y, z) y*x*z/*line 2*/

char this1,b,c;/*line 3*/
int main()/*line 4*/
{
fun(b, a c);/*line 5*/
}/*line 6*/
 
R

Robert Gamble

Hi,

Compilation of the below code fails


#define a this1, /* Comma is intentional line 1*/

#define fun( x, y, z) y*x*z/*line 2*/

char this1,b,c;/*line 3*/
int main()/*line 4*/
{
fun(b, a c); /*Comma is leftout intetionaly line 5*/

}/*line 6*/

with errors as below> gcc test.c

test.c:8:15: macro "fun" requires 3 arguments, but only 2 given
test.c: In function `main':

Macro arguments are not expanded until after the macro itself is
expanded. When the "fun" macro is expanded only 2 arguments are
provided instead of the required 3 which is a constraint violation.

Robert Gamble
 
S

Subra

Macro arguments are not expanded until after the macro itself is
expanded. When the "fun" macro is expanded only 2 arguments are
provided instead of the required 3 which is a constraint violation.

Any preprocessor option to avoid this ???
 
R

Robert Gamble

Any preprocessor option to avoid this ???

I doubt it but if it does I'm sure it's in the documentation. What
are you trying to accomplish?

Robert Gamble
 
K

Keith Thompson

The above was written by Robert Gamble. Please don't delete
attribution lines.
Any preprocessor option to avoid this ???

I doubt it.

The C standard doesn't specify "options" to the preprocessor or to the
compiler; it merely specifies how the compiler is required to behave.
You wrote a macro that requires 3 arguments, and you passed it only 2
arguments. That's a constraint violation, and a diagnostic is
required; in most implementations, the compilation will be rejected.

The solution is to change the macro so it requires 2 arguments, or to
change the invocation so it passes 3 arguments.

C99 introduces variadic macros; your compiler may or may not support
them. But I don't know if that's really what you're looking for.

What are you really trying to do?
 
S

Subra

I doubt it.

The C standard doesn't specify "options" to the preprocessor or to the
compiler; it merely specifies how the compiler is required to behave.
You wrote a macro that requires 3 arguments, and you passed it only 2
arguments. That's a constraint violation, and a diagnostic is
required; in most implementations, the compilation will be rejected.

The solution is to change the macro so it requires 2 arguments, or to
change the invocation so it passes 3 arguments.

C99 introduces variadic macros; your compiler may or may not support
them. But I don't know if that's really what you're looking for.

What are you really trying to do?

I have third party library which was taking 2 args for a macro as
below.

_RW_VAL_ALLOC(a,b) a*b // It is used by platforms HPUX, Solaris

Now the new version of library takes 3 args

_RW_VAL_ALLOC(a,c,b) c*a*b // It is used by LINUX

My code which makes the call to _RW_VAL_ALLOC have to select different
versions
of the macro depending on the platfrom

So my code is like below

#if defined(NEW_VERSION_RW)
#define PIN_ALLOC_VAL argPresnt,
#else
#define PIN_ALLOC_VAL
#endif

int main()
{
int a, b, argPresent;
_RW_VAL_ALLOC(a,
PIN_ALLOC_VAL // Only when we use the new version of
lib, it should get
// replaced by a arg.
b);

}

This solution is not working.
 
R

Robert Gamble

I have third party library which was taking 2 args for a macro as
below.

_RW_VAL_ALLOC(a,b) a*b // It is used by platforms HPUX, Solaris

Now the new version of library takes 3 args

_RW_VAL_ALLOC(a,c,b) c*a*b // It is used by LINUX

My code which makes the call to _RW_VAL_ALLOC have to select different
versions
of the macro depending on the platfrom

So my code is like below

#if defined(NEW_VERSION_RW)
#define PIN_ALLOC_VAL argPresnt,
#else
#define PIN_ALLOC_VAL
#endif

int main()
{
int a, b, argPresent;
_RW_VAL_ALLOC(a,
PIN_ALLOC_VAL // Only when we use the new version of
lib, it should get
// replaced by a arg.
b);

}

This solution is not working.

How about this:

<==CUT==>
#if defined(NEW_VERSION_RW)
#define MY_RW_VAL_ALLOC(a, c, b) _RW_VAL_ALLOC(a, c, b)
#else
#define MY_RW_VAL_ALLOC(a, c, b) _RW_VAL_ALLOC(a, b)
#endif

MY_RW_VAL_ALLOC(a, c, b)
<==CUT==>

$ gcc -E test.c
_RW_VAL_ALLOC(a, b)

$ gcc -E -DNEW_VERSION_RW test.c
_RW_VAL_ALLOC(a, c, b)

Robert Gamble
 
S

Subra

How about this:

<==CUT==>
#if defined(NEW_VERSION_RW)
#define MY_RW_VAL_ALLOC(a, c, b) _RW_VAL_ALLOC(a, c, b)
#else
#define MY_RW_VAL_ALLOC(a, c, b) _RW_VAL_ALLOC(a, b)
#endif

MY_RW_VAL_ALLOC(a, c, b)
<==CUT==>

$ gcc -E test.c
_RW_VAL_ALLOC(a, b)

$ gcc -E -DNEW_VERSION_RW test.c
_RW_VAL_ALLOC(a, c, b)

Robert Gamble
I will be using the above fix ! Thank you Robert.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top