## preprocessing issue

N

new

Hi all,
I have the program as below:
----------------------
#include<stdio.h>

#define FF(x,b) { \
struct ret *t; \
t->##x = b; \
}

struct ret {
int *a;
};
int main()
{
int y =10,*g;
struct ret *s;
g =&y;
FF(a,g);
printf("val:%x %x\n",s->a,g);
return 0;
}

----------------
When I compile the get the below error:
field.c:17:1: pasting "->" and "a" does not give a valid preprocessing
token

Can anyone please help in finding the cause of this error?
I'm using gcc version 3.4.6 20060404 (Red Hat 3.4.6-9)

Thanks in adv.
 
E

Eric Sosman

new said:
Hi all,
I have the program as below:
----------------------
#include<stdio.h>

#define FF(x,b) { \
struct ret *t; \
t->##x = b; \
}

struct ret {
int *a;
};
int main()
{
int y =10,*g;
struct ret *s;
g =&y;
FF(a,g);
printf("val:%x %x\n",s->a,g);
return 0;
}

----------------
When I compile the get the below error:
field.c:17:1: pasting "->" and "a" does not give a valid preprocessing
token

Can anyone please help in finding the cause of this error?

It's just what the error message says: `->' is a valid token,
and `a' is a valid token, but `->a' is not a valid token. If the
compiler encountered `->a' in ordinary source text, it would split
it into the two tokens `->' and `a', but you've told it to paste
all three characters together and (somehow) treat them as one thing.

If[*] you're trying to generate a reference to the `a' element
of the `struct ret' structure pointed to by `t', just get rid of the
`##': you want `t' and `->' and `a' to be individual tokens.

[*] I say "if" because I can't tell what you're trying to do.
The code fragment is riddled with other errors, and even if you
get it to compile I can't imagine it doing anything sensible.
Perhaps if you would explain your purpose someone would have a
suggestion about how to accomplish it -- but the code you've shown
is not a good start towards anything.
 
J

James Kuyper

new said:
Hi all,
I have the program as below:
----------------------
#include<stdio.h>

#define FF(x,b) { \
struct ret *t; \
t->##x = b; \
}

struct ret {
int *a;
};
int main()
{
int y =10,*g;
struct ret *s;
g =&y;
FF(a,g);
printf("val:%x %x\n",s->a,g);
return 0;
}

The ## operator takes two pre-processing tokens and merges them into a
single pre-processing token. This can be very useful when you want to,
for instance, create a single identifier by merging two other identifiers.

However, what you want to create is "t->a = b;". That contains 6
preprocessing tokens: "t", "->", "a", "=", "b" and ";". with the ##
operator, you're creating only 5 preprocessing tokens, and one of them
("->a") has the wrong format to be a valid preprocessing token.

What you should be writing is:

t->x = b;
 
I

Ike Naar

#include<stdio.h>

#define FF(x,b) { \
struct ret *t; \
t->##x = b; \
}

struct ret {
int *a;
};
int main()
{
int y =10,*g;
struct ret *s;
g =&y;
FF(a,g);
printf("val:%x %x\n",s->a,g);
return 0;
}

----------------
When I compile the get the below error:
field.c:17:1: pasting "->" and "a" does not give a valid preprocessing
token

Can anyone please help in finding the cause of this error?

The ## operator in a macro expansion tries to paste its operands into
a single token; here's an example:

#define paste(x,y) x##y
int paste(aba,cab);

After preprocessing, this gives:

int abacab ;

(showing the tokens separated by whitespace for clarity).
In the macro you've shown:

#define FF(x,b) { struct ret *t; t->##x = b; }
FF(a,g);

expands to

{ struct ret * t ; t ->a = g ; }

(tokens again separated by whitespace).
As you see, your macro tries to create the token ->a
which makes little sense.
Is there any reason why you're not using the simpler

#define FF(x,b) { struct ret *t; t->x = b; }

(without the ## ) ?
 
N

new

The ## operator takes two pre-processing tokens and merges them into a
single pre-processing token. This can be very useful when you want to,
for instance, create a single identifier by merging two other identifiers..

However, what you want to create is "t->a = b;". That contains 6
preprocessing tokens: "t", "->", "a", "=", "b" and ";". with the ##
operator, you're creating only 5 preprocessing tokens, and one of them
("->a") has the wrong format to be a valid preprocessing token.

What you should be writing is:

t->x = b;

Thanks for all your replies.
But why did the same program didn't throw errors with the older gcc
version?
gcc 2.95.3
Any reason for removing this format?
 
K

Keith Thompson

Richard Heathfield said:
new said:



The Standard says: "If the result is not a valid preprocessing token,
the behavior is undefined." Since it isn't a syntax error or a
constraint violation, no diagnostic message is required.
Implementations are free choose whether or not to diagnose the
mistake. But, whether they do or not, it's still a mistake.

<snip>

To put it another way, it appears that the older gcc failed to
diagnose this error. It was doing you no favors by letting you
write incorrect C. In newer versions of gcc, the flaw is corrected,
and you get an error message. Strictly speaking the standard
doesn't require the error to be diagnosed, and an implementation
conceivably *could* define some useful meaning for the code, but
there's no much point in doing so.
 

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,994
Messages
2,570,222
Members
46,810
Latest member
Kassie0918

Latest Threads

Top