473,320 Members | 1,865 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Help with #define

Hi all,
I have the below #defines
#define NUMBER1 30
#define NUMBER2 50
#define SUM (NUMBER1+NUMBER2)
#define STRING1 "Byte: \x30"
#define STRING2 "Byte: \x50"

If I change NUMBER1 and NUMBER2 I must change STRING1 and STRING2
consequently.
Is there a method to #define STRING1 and STRING2 at preprocessor-time
with a number defined with a #define embedded in the string?

Nov 14 '05 #1
9 3067
On Thu, 22 Apr 2004 16:35:59 GMT, "pozz" <pN************@libero.it> wrote:
#define NUMBER1 30
#define NUMBER2 50
#define SUM (NUMBER1+NUMBER2)
#define STRING1 "Byte: \x30"
#define STRING2 "Byte: \x50"

If I change NUMBER1 and NUMBER2 I must change STRING1 and STRING2
consequently.
Is there a method to #define STRING1 and STRING2 at preprocessor-time
with a number defined with a #define embedded in the string?


Sort of....

#include <stdio.h>

#define NUMBER1 30
#define NUMBER2 50
#define SUM (NUMBER1+NUMBER2)
#define STRING1 "Byte: \\x30"
#define STRING2 "Byte: \\x50"

#define NUM(x) #x
#define STRINGx(x) "Byte: \\x"##NUM(x)

int main(void)
{
printf("NUMBER1 = %d\n", NUMBER1);
printf("NUMBER2 = %d\n", NUMBER2);
printf("SUM = %d\n", SUM);

printf("STRING1 = %s\n", STRING1);
printf("STRING2 = %s\n", STRING2);

puts("Stringized macros:\n");
printf("STRING3 = %s\n", STRINGx(NUMBER1));
printf("STRING4 = %s\n", STRINGx(NUMBER2));

return 0;
}

Note that if you wanted to display the literal text "Byte: \x30", the above
will do what you want. If you intended to display "Byte: x" where x is the
character with the value 0x30, the above code will not work.

In that case, I'd abandon the macro idea and simply use the NUMBER1 macro
as an argument to printf itself:

printf("Byte: %c\n", NUMBER1);

--
Robert B. Clark (email ROT13'ed)
Visit ClarkWehyr Enterprises On-Line at http://www.3clarks.com/ClarkWehyr/
Nov 14 '05 #2
Robert B. Clark wrote:
Sort of....

#include <stdio.h>

#define NUMBER1 30
#define NUMBER2 50
#define SUM (NUMBER1+NUMBER2)
#define STRING1 "Byte: \\x30"
#define STRING2 "Byte: \\x50"

#define NUM(x) #x
#define STRINGx(x) "Byte: \\x"##NUM(x)

int main(void)
{
printf("NUMBER1 = %d\n", NUMBER1);
printf("NUMBER2 = %d\n", NUMBER2);
printf("SUM = %d\n", SUM);

printf("STRING1 = %s\n", STRING1);
printf("STRING2 = %s\n", STRING2);

puts("Stringized macros:\n");
printf("STRING3 = %s\n", STRINGx(NUMBER1)); gcc3.3: pasting ""Byte: \\x"" and "NUM" does not give a valid
preprocessing token printf("STRING4 = %s\n", STRINGx(NUMBER2)); gcc3.3: pasting ""Byte: \\x"" and "NUM" does not give a valid
preprocessing token
return 0;
}


Nov 14 '05 #3
pozz wrote:
Hi all,
I have the below #defines
#define NUMBER1 30
#define NUMBER2 50
#define SUM (NUMBER1+NUMBER2)
#define STRING1 "Byte: \x30"
#define STRING2 "Byte: \x50"

If I change NUMBER1 and NUMBER2 I must change STRING1 and STRING2
consequently.
Is there a method to #define STRING1 and STRING2 at preprocessor-time
with a number defined with a #define embedded in the string?


Here's what might help you a bit further (as seen on K&R, page 231).

#define cat(a,b) a #b
#define xcat(a,b) cat(a,b)

#define NUMBER 30
#define STRING xcat("Byte: ", NUMBER)

Without success I've tried several things to get the \xNUMBER into the
STRING using CPP operators # and ##. Trying to paste an illegal 'token':
\x, to a number was what I bumped in to. Not wanting to spend too much
time, I gave up. I'm curious if it is at all possible.

BTW, are you aware of the fact that 30 != '\x30'? Maybe you could tell
more about what you want, there might be alternatives.

Cheers,

Kees

Nov 14 '05 #4
- CASE - <ca**@feasture.com> wrote:
Robert B. Clark wrote:
Sort of....

#include <stdio.h>

#define NUMBER1 30
#define NUMBER2 50
#define SUM (NUMBER1+NUMBER2)
#define STRING1 "Byte: \\x30"
#define STRING2 "Byte: \\x50"

#define NUM(x) #x
#define STRINGx(x) "Byte: \\x"##NUM(x)
#define STRINGx(x) "Byte: \\x" NUM(x)

int main(void)
{
printf("NUMBER1 = %d\n", NUMBER1);
printf("NUMBER2 = %d\n", NUMBER2);
printf("SUM = %d\n", SUM);

printf("STRING1 = %s\n", STRING1);
printf("STRING2 = %s\n", STRING2);

puts("Stringized macros:\n");
printf("STRING3 = %s\n", STRINGx(NUMBER1));

gcc3.3: pasting ""Byte: \\x"" and "NUM" does not give a valid
preprocessing token
printf("STRING4 = %s\n", STRINGx(NUMBER2));

gcc3.3: pasting ""Byte: \\x"" and "NUM" does not give a valid
preprocessing token

return 0;
}


literal strings don't need explicit concatenation, the preprocessor
does this automagically.

--
Z (Zo**********@daimlerchrysler.com)
"LISP is worth learning for the profound enlightenment experience
you will have when you finally get it; that experience will make you
a better programmer for the rest of your days." -- Eric S. Raymond
Nov 14 '05 #5
In <c9********************************@4ax.com> Robert B. Clark <ep****@3pynexf.pbz> writes:
On Thu, 22 Apr 2004 16:35:59 GMT, "pozz" <pN************@libero.it> wrote:
#define NUMBER1 30
#define NUMBER2 50
#define SUM (NUMBER1+NUMBER2)
#define STRING1 "Byte: \x30"
#define STRING2 "Byte: \x50"

If I change NUMBER1 and NUMBER2 I must change STRING1 and STRING2
consequently.
Is there a method to #define STRING1 and STRING2 at preprocessor-time
with a number defined with a #define embedded in the string?


Sort of....

#include <stdio.h>

#define NUMBER1 30
#define NUMBER2 50
#define SUM (NUMBER1+NUMBER2)
#define STRING1 "Byte: \\x30"
#define STRING2 "Byte: \\x50"

#define NUM(x) #x
#define STRINGx(x) "Byte: \\x"##NUM(x)


Nice try, but it's undefined behaviour:

3 For both object-like and function-like macro invocations, before
^^^^^^
the replacement list is reexamined for more macro names to
replace, each instance of a ## preprocessing token in the
replacement list (not from an argument) is deleted and the
preceding preprocessing token is concatenated with the following
preprocessing token. Placemarker preprocessing tokens are
handled specially: concatenation of two placemarkers results in
a single placemarker preprocessing token, and concatenation of a
placemarker with a non-placemarker preprocessing token results
in the non-placemarker preprocessing token. If the result is
^^^^^^^^^^^^^^^^
not a valid preprocessing token, the behavior is undefined. The
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^
resulting token is available for further macro replacement. The
order of evaluation of ## operators is unspecified.

So, the preprocessor concatenates "Byte: \\x" and NUM and ends up with
"Byte: \\x"NUM which is not a valid preprocessing token, hence undefined
behaviour. Some preprocessors just go on and do what you intended, which
is allowed by undefined behaviour, gcc's is more friendly and it diagnoses
the code.

Fortunately, the ## operator in your macro was a mistake in the first
place: you don't want to create a new preprocessing token out of two
preprocessing tokens. All you want to achieve is generating two adjacent
string literals, that will be spliced together in translation phase 6:

#define STRINGx(x) "Byte: \\x" NUM(x)

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #6
"- Kees van der Bent -" <kv*@mbalance.moc> ha scritto nel messaggio
news:40*********************@news.xs4all.nl...
pozz wrote:
[CUT]
Here's what might help you a bit further (as seen on K&R, page 231).

#define cat(a,b) a #b
#define xcat(a,b) cat(a,b)

#define NUMBER 30
#define STRING xcat("Byte: ", NUMBER)

No, it doesn't resolve my problem. In that way, I obtain
"Byte: " "30" that is "Byte: 30". I want "Byte: \x30", a
7-characters string (not counting \0 character).
BTW, are you aware of the fact that 30 != '\x30'?
Oh, yes. I know. I can define NUMBER in this way:
#define NUMBER 0x30
or
#define NUMBER 48
Maybe you could tell
more about what you want, there might be alternatives.


I want to write in an EEPROM a sequence of bytes, some ASCII
characters and some binary, using a single routine that accepts
a pointer parameters.

#define NUMBER 48
#define STRING "Hello \x30"
....
eeprom_write( STRING );
....

I can create the string at run-time, but NUMBER is costant so it's not
necessary.
But I want to use NUMBER in a mathematical expression too, so I can't
define it as
#define NUMBER "48"
Nov 14 '05 #7


pozz wrote:
No, it doesn't resolve my problem. In that way, I obtain
"Byte: " "30" that is "Byte: 30". I want "Byte: \x30", a
7-characters string (not counting \0 character). I want to write in an EEPROM a sequence of bytes, some ASCII
characters and some binary, using a single routine that accepts
a pointer parameters.

#define NUMBER 48
#define STRING "Hello \x30"
...
eeprom_write( STRING );
...

I can create the string at run-time, but NUMBER is costant so it's not
necessary.
But I want to use NUMBER in a mathematical expression too, so I can't
define it as
#define NUMBER "48"


When the length of STRING is indeed always 7 then:

#define STRING "Byte: \x30"
#define NUMBER STRING[6]

This works, but because the definition of NUMBER has an
*implicit* dependency on the format of STRING, it feels
tricky/obscure.

Cheers,

Kees

Nov 14 '05 #8
"Case -" <no@no.no> ha scritto nel messaggio
news:40**********************@dreader2.news.tiscal i.nl...


pozz wrote:
No, it doesn't resolve my problem. In that way, I obtain
"Byte: " "30" that is "Byte: 30". I want "Byte: \x30", a
7-characters string (not counting \0 character).

I want to write in an EEPROM a sequence of bytes, some ASCII
characters and some binary, using a single routine that accepts
a pointer parameters.

#define NUMBER 48
#define STRING "Hello \x30"
...
eeprom_write( STRING );
...

I can create the string at run-time, but NUMBER is costant so it's not
necessary.
But I want to use NUMBER in a mathematical expression too, so I can't
define it as
#define NUMBER "48"


When the length of STRING is indeed always 7 then:

#define STRING "Byte: \x30"
#define NUMBER STRING[6]

This works, but because the definition of NUMBER has an
*implicit* dependency on the format of STRING, it feels
tricky/obscure.


Hmm..., I don't like that solution. NUMBER is the master symbol
and STRING is derived from that.
Nov 14 '05 #9
pozz wrote:
#define NUMBER1 30
#define STRING1 "Byte: \x30"

If I change NUMBER1 [...] I must change STRING1


I sort of have an answer. It doesn't work, but it's very close and
just might work on some compiler, somewhere.

#define STR( x ) #x
#define XSTR( x ) STR( x )
#define CAT( a, b ) a##b
#define BYTE( x ) XSTR( CAT( \u00, x ) )

#define NUMBER1 30
#define STRING1 "Byte: " BYTE( NUMBER1 )

This would get around the problem of \xNN not being part of a valid
identifier, except that there's a bizarre constraint with universal
character names that does not allow them to represent characters in
the range you likely want. (Almost all of ASCII is forbidden.)

--
++acr@,ka"
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: wukexin | last post by:
Help me, good men. I find mang books that introduce bit "mang header files",they talk too bit,in fact it is my too fool, I don't learn it, I have do a test program, but I have no correct doing...
13
by: webzila | last post by:
Hello, I have to write a program for an 8051 micro-controller using micro-C to monitor Switch 1 and if the switch in pushed the message "switch 1 pushed" should be displayed in the LCD. Also the...
1
by: Paul Ferrill | last post by:
Can anyone help with the code to call the following C routines: /* Memory model that allows to access memory at offsets of lzo_uint. */ #if !defined(__LZO_MMODEL) # if (LZO_UINT_MAX <=...
20
by: paolo.arimado | last post by:
Dear everyone, Can someone please help me on my HW. I'm trying to write a program that will display the following: * *** ***** ******* *********
9
by: Jerret Johnson | last post by:
A challenged co-worker of mine challenged me to come up with a perverse example of a conforming Standard C program. This is by no means a gold medal winner in a C obfuscation contest, but...
8
by: aaron | last post by:
I have an array of id=>category: =Automotive Parts =Automotive Parts\Domestic =Automotive Parts\Foreign =Building Supplies =Building Supplies\Lumber =Building Supplies\Lumber\Hardwood ...
5
by: weidongtom | last post by:
Hi, I tried to implement the Universal Machine as described in http://www.boundvariable.org/task.shtml, and I managed to get one implemented (After looking at what other's have done.) But when I...
5
by: iapx86 | last post by:
My parser project calls for a computed goto (see code below). The C preprocessor delivers the desired result, but is ugly. Template metaprogramming delivers results I do not understand. Can...
11
by: A.C. | last post by:
hi i m declaring a structure globally & there is func1 & main. i m assigning the value to variable(this is a pointer) of structure in fun1 & want to print it in main. this is same kind of...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.