472,961 Members | 1,538 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,961 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 3042
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...
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
2
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

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.