# and ## operators

M

Mantorok Redgormor

When is it appropriate to use # and ##? I have been told that ## is
not useful at all.






nethlek
 
E

Emmanuel Delahaye

In said:
When is it appropriate to use # and ##? I have been told that ## is
not useful at all.

I use it every day. For example, it very useful for local debug macros.

Say, I have a structure that represent some configuration data:

typedef struct
{
unsigned int foo;
some_enum_type bar;
unsigned long baz;
}
config_s;

At a certain stage of my code, I want a trace of the values on the console.

Ok, I can write

printf ("foo = %u", p->foo);
printf ("bar = %u", (unsigned int) p->bar);
printf ("baz = %ul", p->baz);

which is rapidly boring is I have 20 elements or more...

What can be done to help and avoid errors is to ask the proprocessor to
write the code for you:

#define PRT(a) \
printf ("%4s = %ul", #baz, (unsigned long) p-> ## a)

PRT (foo);
PRT (bar);
PRT (baz);

#undef PRT
 
K

Kevin Easton

Emmanuel Delahaye said:
I use it every day. For example, it very useful for local debug macros.

Say, I have a structure that represent some configuration data:

typedef struct
{
unsigned int foo;
some_enum_type bar;
unsigned long baz;
}
config_s;

At a certain stage of my code, I want a trace of the values on the console.

Ok, I can write

printf ("foo = %u", p->foo);
printf ("bar = %u", (unsigned int) p->bar);
printf ("baz = %ul", p->baz);

which is rapidly boring is I have 20 elements or more...

What can be done to help and avoid errors is to ask the proprocessor to
write the code for you:

#define PRT(a) \
printf ("%4s = %ul", #baz, (unsigned long) p-> ## a)

I think you mean #a there. In the expression p->bar, there are three
tokens: "p", "->" and "bar". So you don't need the ## token pasting
operator here - this definition works:

#define PRT(a) \
printf ("%4s = %ul", #a, (unsigned long) p-> a)

To the OP: the ## operator is needed whenever you need to create a
single token from multiple tokens - this only ever occurs in macros.
Say you had some code like this:

func_a(s->data_a);
func_b(s->data_b);
func_c(s->data_c);
func_d(s->data_d);
func_e(s->data_e);

and you wanted to use a macro to make it less error-prone. You could do
that like this:

#define DO_THING(x) func_ ## x (s -> data ## x)

DO_THING(a);
DO_THING(b);
DO_THING(c);
DO_THING(d);
DO_THING(e);

- Kevin.
 
E

Emmanuel Delahaye

In 'comp.lang.c' said:
I think you mean #a there.

Oops, absolultly. Yet another victim of copy and paste...
In the expression p->bar, there are three
tokens: "p", "->" and "bar". So you don't need the ## token pasting
operator here - this definition works:

True enough, my example was poor.
 
M

mbs

When is it appropriate to use # and ##?

the # operator helps you harness the power of the c-preprocessor.

suppose you define a macro like this:
#define SHOW_INT( var ) printf( #var"=%d\n", var );

and call it later:

int i=800;
...
SHOW_INT( i );
...

it would expend to
printf( "i""=%d\n", i );
and would print
i=800
to stdout.

Here is my version of SHOW, which I use daily:
#define SHOW( val, fmt ) { fprintf( stderr, "%d "#val"=#fmt"\n",
__LINE__, (val) ); }

this macro prints the what it is about to do to stderr and the does
it:
#define DODBG( cmd ) { fprintf( stderr, "%d doing "#cmd"\n",
__LINE__ ); {cmd;} }
..
I have been told that ## is not useful at all

It is. There's an example in K&R, but the book is not here now.

Michael.
 
J

Jack Klein

S

Steve Zimmerman

Mantorok said:
When is it appropriate to use # and ##? I have been told that ## is
not useful at all.


Mantorok,

Thank you for your post. I don't know if ## is useful at all.
The following program uses ##, but not in a very useful way.


#include <stdio.h>
#include <string.h>

#define paste(front, back) front ## back /* p. 92, K&R2 */

int main()
{
char *paste(Rama, nujan); /* char *Ramanujan; */

strcpy(Ramanujan, "Ramanujan is great");

printf("%s\n", paste(Rama, nujan));

return 0;
}

Output of program: Ramanujan is great
Aborted

Why does this program's output contain two streams (stdout and stderr)?

--Steve
 
I

Irrwahn Grausewitz

Steve Zimmerman said:
Mantorok,

Thank you for your post. I don't know if ## is useful at all.
The following program uses ##, but not in a very useful way.


#include <stdio.h>
#include <string.h>

#define paste(front, back) front ## back /* p. 92, K&R2 */

int main()
{
char *paste(Rama, nujan); /* char *Ramanujan; */

strcpy(Ramanujan, "Ramanujan is great");

You failed to allocate some memory for 'Ramanujan' to point to.
printf("%s\n", paste(Rama, nujan));

return 0;
}

Output of program: Ramanujan is great
Aborted

Why does this program's output contain two streams (stdout and stderr)?

The abort message, induced by the error above, was printed to stderr.

Regards

Irrwahn
 

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,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top