stringizing a hex value in the preprocessor

H

Henry Townsend

Consider the little program below. It simply attempts to determine what
version of what compiler it was built with via documented preprocessor
macros and print out the result. When the compiler is gcc it works fine,
because __VERSION__ is supplied as a string. But identifying the Sun
compiler is harder because it provides __SUNPRO_C as a numerical value
(equal in my case to 0x580). My attempt to stringify it produces an error:

% cc -g -o foo foo.c
"foo.c", line 13: invalid source character: '#'
"foo.c", line 13: syntax error before or at: 0x580
cc: acomp failed for foo.c

Is there a way to do this?

Thanks,
HT

--------------------------------------------------------------
#include <stdio.h>

#if defined(__GNUC__)
#define COMPILER_STRING "gcc " __VERSION__
#elif defined(__SUNPRO_C)
#define COMPILER_STRING "SunStudio " #__SUNPRO_C
#else
#define COMPILER_STRING "unknown compiler/version"
#endif

int main(void)
{
printf("Compiled with %s\n", COMPILER_STRING);
return 0;
}
 
S

Suman

Henry said:
Consider the little program below. It simply attempts to determine what
version of what compiler it was built with via documented preprocessor
macros and print out the result. When the compiler is gcc it works fine,
because __VERSION__ is supplied as a string. But identifying the Sun
compiler is harder because it provides __SUNPRO_C as a numerical value
(equal in my case to 0x580). My attempt to stringify it produces an error:

Here's my try:

#include <stdio.h>

#define str(x) #x
#define xstr(x) str(x)
#define paste(x, y) x ## y

#define __SUNPRO_C 0x580
#if defined(__IGNUC__)
#define COMPILER_STRING "gcc " __VERSION__
#elif defined(__SUNPRO_C)
#define COMPILER_STRING xstr(paste(SunStudio, xstr(__SUNPRO_C)))
#else
#define COMPILER_STRING "unknown compiler/version"
#endif

int main(void)
{
printf("Compiled with %s\n", COMPILER_STRING);
return 0;
}

and this was compiled with gcc -std=c99 -Wall.
 
S

Suman

Suman said:
Here's my try:

a tad improved:
--------------------------------------><----------------------------------------------------------------
#include <stdio.h>

#define str(x) #x
#define xstr(x) str(x)
#define paste(x, y) x ## y

#define __SUNPRO_C 0x580
#if defined(__IGNUC__)
#define COMPILER_STRING "gcc " __VERSION__
#elif defined(__SUNPRO_C)
#define COMPILER_STRING xstr(SunStudio xstr(__SUNPRO_C))
#else
#define COMPILER_STRING "unknown compiler/version"
#endif

int main(void)
{
printf("Compiled with %s\n", COMPILER_STRING);
return 0;
}
--------------------------------------><----------------------------------------------------------------
gcc -std=c99 -Wall -pedantic -ansi. And, excuse the ignominious
__IGNU__.
I don't have a Sun compiler to play with :)

HTH
 
H

Henry Townsend

Suman said:
Here's my try:

a tad improved:
[snip]

Yes, that works. Actually it prints:

Compiled with SunStudio "0x580"

and a tweak I made to use the line:

#define COMPILER_STRING "SunStudio " ## xstr(__SUNPRO_C)

removes the quotes to give:

Compiled with SunStudio 0x580

Which is what I was looking for. Thanks!

HT
 
R

Raghu

Here is My try :

#include <stdio.h>

#define str(x) #x
#define paste(x,y) x##y
#define Mystr(x) str(x)


#define __SUNPRO_C 0x580

#if defined(__IGNUC__)

#define COMPILER_STRING "gcc " __VERSION__

#elif defined(__SUNPRO_C)

#define COMPILER_STRING paste("SunStudio",Mystr(__SUNPRO_C))

#else

#define COMPILER_STRING "unknown compiler/version"

#endif

int main(void)
{
printf("Compiled with %s\n", COMPILER_STRING);
return 0;
}


-- Raghu.


Henry Townsend said:
Suman said:
Here's my try:

a tad improved:
[snip]

Yes, that works. Actually it prints:

Compiled with SunStudio "0x580"

and a tweak I made to use the line:

#define COMPILER_STRING "SunStudio " ## xstr(__SUNPRO_C)

removes the quotes to give:

Compiled with SunStudio 0x580

Which is what I was looking for. Thanks!

HT
 
H

Hubble

Except that I would not use small letters for macros. Or did I miss
something? The solution is good but hard to read for me.

Hubble
 
M

Maxim Yegorushkin

Henry said:
Consider the little program below. It simply attempts to determine what
version of what compiler it was built with via documented preprocessor
macros and print out the result. When the compiler is gcc it works fine,
because __VERSION__ is supplied as a string. But identifying the Sun
compiler is harder because it provides __SUNPRO_C as a numerical value
(equal in my case to 0x580). My attempt to stringify it produces an error:

Why not just use a simple shell script invoked by makefile to do just
that?

$ cat build_string
#! /bin/bash

echo "namespace $1 { "
echo "extern char const build_string[] = "
echo \"$(date -u +"%F %T UTC") \"
echo \"$(g++ --version | head -n 1)\"
echo ";"
echo "}"

bash-3.00$ cat Makefile

....
all: app
app: dirs build_string $(app_obj)
$(CXX) -o $(bin_dir)app $(app_obj) $(LDFLAGS)
....
..PHONY : dirs clean build_string install
build_string:
./build_string app > $(src_dir)build_string.cpp
....
 
P

pete

Hubble wrote:
I would not use small letters for macros. Or did I miss
something? These macros is good but hard to read for me.

The first two of those macros are copied from the C standard.
That makes it easy to look them up in the standard
if you want to see what the standard has to say about them.
Otherwise, neither would I write them that way.
 
P

pete

pete said:
The first two of those macros are copied from the C standard.
That makes it easy to look them up in the standard
if you want to see what the standard has to say about them.
Otherwise, neither would I write them that way.

I suppose they wouldn't be that difficult to look up
if they were in caps and you knew they were in the standard.
There's a couple of things
that I copy from the C standard in my code.

For example

int main(int argc, char *argv[])

even though

int main(int argc, char **argv)

is really my prefered style.
 
K

Keith Thompson

Hubble said:
Sorry for using google:
[snip]

No need to apologize; using google is perfectly acceptable as long as
you use it correctly. (Some people have killfiled everything posted
through groups.google.com, but that's their decision.)
 
S

Suman

pete said:
The first two of those macros are copied from the C standard.
That makes it easy to look them up in the standard
if you want to see what the standard has to say about them.
Otherwise, neither would I write them that way.

Addendum:
The third, is a modified form of what you find in K&R 2:
#define paste(front, back) front ## back
 
P

pete

Suman said:
Addendum:
The third, is a modified form of what you find in K&R 2:
#define paste(front, back) front ## back

That's good enough for me.

It might be worth keeping in mind
that there's a few deviations here and there in standard C,
from what's generally considered good style.
FILE is a typedef, stdout is a macro.
 

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,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top