C predefined macros and portability

S

sathya_me

friends,
Please go through the following code which I have downloaded from Bob
Stout (Snippets):



#include <stdio.h>



void main(void) /* Actually, void main() is non-ANSI/ISO */

{

int version;



#if defined(__ZTC__)

#ifdef __SC__

printf("Symantec C++ ver. %x.%x\n", __SC__ >> 8, __SC__ & 0xff);

#else

printf("Zortech C++ ver. %x.%xr%x\n",

__ZTC__ >> 8, (__ZTC__ >> 4) & 0xf, __ZTC__ & 0xf);

#endif

#elif defined(__WATCOMC__)

printf("Watcom C/C++ ver. %d.%d\n",

__WATCOMC__ / 100, __WATCOMC__ % 100);

#elif defined(__TURBOC__)

version = __TURBOC__;

if (0x295 > version)

{

printf("Borland Turbo C ver. %x.%02x\n",

version >> 8, version & 0xff);

}

else if (0x400 <= version)

{

printf("Borland C++ ver. %x.%x\n",

(version >> 8) - 1, (version & 0xff) >> 4);

}

else if (0x297 > version)

printf("Borland Turbo C++ ver. 1.%02x\n", version - 0x295);

else printf("Borland C++ ver. 2.%02x\n", version - 0x297);

#elif defined(_QC)

printf("Microsoft Quick C ver. %d.%d\n", _QC / 100, _QC % 100);

#elif defined(_MSC_VER)

printf("Microsoft C(/C++) ver. %d.%d\n",

_MSC_VER / 100, _MSC_VER % 100);

#elif defined(__POWERC)

printf ("MIX Power C ver. %d\n", __POWERC);

#else

puts("Unknown compiler!");

#endif

}


I have downloaded the above program which prints the specified compiler
by which the code is been compiled. I have tested with MSVC and TC++, GCC.
The out-put was exactly same as excepted. It throws "Unknown compiler!"
for GCC. Even though the following code did use some of the non- ANSI
standard
specific can anybody explain the following:
1)__ZTC__ , __SC__ etc. are predefined macros (correct me if I am
wrong).
Can any body explain how this work during the compile / run time?
(I am
not sure weather this evaluated during the compile or run time)

2) Why there are some of the operators are used in the printf. Can
any body
explain why?

3) Is this the way the C code becomes portable. If yes then is it
possible
to make a C code portable with different OS, processors.

4)I want to know more about the above. Any link on the web

If the above is discussed in FAQ or it is a OT please guide me to the
correct
NG.

Thanks

--
"Combination is the heart of chess"
A.Alekhine
Mail to:
sathyashrayan25 AT yahoo DOT com
(remove the AT and DOT)
 
J

Jens.Toerring

sathya_me said:
Please go through the following code which I have downloaded from Bob
Stout (Snippets):
#include <stdio.h>
void main(void) /* Actually, void main() is non-ANSI/ISO */
{
int version;
#if defined(__ZTC__)
#ifdef __SC__
printf("Symantec C++ ver. %x.%x\n", __SC__ >> 8, __SC__ & 0xff);
#else
printf("Zortech C++ ver. %x.%xr%x\n",
__ZTC__ >> 8, (__ZTC__ >> 4) & 0xf, __ZTC__ & 0xf);
#endif
#elif defined(__WATCOMC__)
printf("Watcom C/C++ ver. %d.%d\n",
__WATCOMC__ / 100, __WATCOMC__ % 100);
#elif defined(__TURBOC__)
version = __TURBOC__;
if (0x295 > version)
{
printf("Borland Turbo C ver. %x.%02x\n",
version >> 8, version & 0xff);
}
else if (0x400 <= version)
{
printf("Borland C++ ver. %x.%x\n",
(version >> 8) - 1, (version & 0xff) >> 4);
}
else if (0x297 > version)
printf("Borland Turbo C++ ver. 1.%02x\n", version - 0x295);
else printf("Borland C++ ver. 2.%02x\n", version - 0x297);
#elif defined(_QC)
printf("Microsoft Quick C ver. %d.%d\n", _QC / 100, _QC % 100);
#elif defined(_MSC_VER)
printf("Microsoft C(/C++) ver. %d.%d\n",
_MSC_VER / 100, _MSC_VER % 100);
#elif defined(__POWERC)
printf ("MIX Power C ver. %d\n", __POWERC);
#else
puts("Unknown compiler!");
#endif
}
I have downloaded the above program which prints the specified compiler
by which the code is been compiled. I have tested with MSVC and TC++, GCC.
The out-put was exactly same as excepted. It throws "Unknown compiler!"
for GCC. Even though the following code did use some of the non- ANSI
standard specific can anybody explain the following:
1)__ZTC__ , __SC__ etc. are predefined macros (correct me if I am
wrong).
Can any body explain how this work during the compile / run time?
(I am not sure weather this evaluated during the compile or run time)

All the '#ifdef', '#elif', '#else' and '#endif' stuff is dealt with
by the preprocessor. Obviously for example the Watcom compiler defines
a macro named '__WATCOMC__' (and the whole thing only works if no
other of the compilers defines it!). In that case the lines between
the '#elif defined(__WATCOMC__)' and the '#elif defined(__TURBOC__)'
line are the ones that get included into the source code the compiler
is going to see, and if all the other macros are undefined that are
the only lines that will make it into the code.
2) Why there are some of the operators are used in the printf. Can
any body explain why?

For example '__WATCOMC__' seems to be defined as a number that stands
for the compiler version where e.g. 821 would stand for main version
8, subversion 21. All what happens in the second and third argument
to printf() is picking that number apart to get the 8 and the 21. The
same seems to happen (with variations) for the other compilers.
3) Is this the way the C code becomes portable. If yes then is it
possible to make a C code portable with different OS, processors.

All this doesn't got much to do with portability. It just is an
attempt to figure out which compiler is used to compile the
program. For portable C code you _don't_ need that information
at all - if you need to know that you're typically already way
down the slippery road to non-portability.

Regards, Jens
 
S

sathya_me

All the '#ifdef', '#elif', '#else' and '#endif' stuff is dealt with
by the preprocessor. Obviously for example the Watcom compiler defines
a macro named '__WATCOMC__' (and the whole thing only works if no
other of the compilers defines it!). In that case the lines between
the '#elif defined(__WATCOMC__)' and the '#elif defined(__TURBOC__)'
line are the ones that get included into the source code the compiler
is going to see, and if all the other macros are undefined that are
the only lines that will make it into the code.

The preprocessors check the *conditions* inside the top most #if and
#endif block.
If the preprocessor finds the specific condition it prints the message
and exits.
If not then continues. So it happens not during the run time but during
preprocessor time.
(Basic preprocessor evaluation, which I have over looked, I must be more
careful)
For example '__WATCOMC__' seems to be defined as a number that stands
for the compiler version where e.g. 821 would stand for main version
8, subversion 21. All what happens in the second and third argument
to printf() is picking that number apart to get the 8 and the 21. The
same seems to happen (with variations) for the other compilers.

Clear and understood.
All this doesn't got much to do with portability. It just is an
attempt to figure out which compiler is used to compile the
program. For portable C code you _don't_ need that information
at all - if you need to know that you're typically already way
down the slippery road to non-portability.
Asking more of this will make the thread an OT. So concluding.

Thanks
N.Sathyashrayan

--
"Combination is the heart of chess"
A.Alekhine
Mail to:
sathyashrayan25 AT yahoo DOT com
(remove the AT and DOT)
 
J

Jens.Toerring

(e-mail address removed)-berlin.de wrote:
The preprocessors check the *conditions* inside the top most #if and
#endif block.
If the preprocessor finds the specific condition it prints the message
and exits.
If not then continues. So it happens not during the run time but during
preprocessor time.
(Basic preprocessor evaluation, which I have over looked, I must be more
careful)

No, the preprocessor doesn't print anything, that only happens when
you run the final program. It just removes the parts of the program
for which the macros aren't defined and in what remains it expands
the macros.

In the case of only '__WATCOMC__' being defined and it's being 821
you end up with a program that will basically look similar to

void main(void)
{
printf("Watcom C/C++ ver. %d.%d\n",
821 / 100, 821 % 100);
}

This is what then gets compiled and will produce the output
"Watcom C/C++ ver. 8.21" when run.

Regards, Jens
 
S

SM Ryan

# 1)__ZTC__ , __SC__ etc. are predefined macros (correct me if I am
# wrong).
# Can any body explain how this work during the compile / run time?
# (I am
# not sure weather this evaluated during the compile or run time)

Individual compilers often make nonstandard #defines to identify the
compiler to the compiled program. The programs can let the preprocessor
select different versions of the source code that exploit compiler
specific extensions to C, or in some cases a version that patches around
a compiler bug.

# 2) Why there are some of the operators are used in the printf. Can
# any body
# explain why?

Compiler specific. Those compilers probably set their special #define
to encoded version number; the arithmetic is then to extract that
version number.

# 3) Is this the way the C code becomes portable. If yes then is it
# possible
# to make a C code portable with different OS, processors.

All standard conforming compilers should compile the same standard
conforming program. These are to identify nonstandard extensions
and compiler bugs.

# 4)I want to know more about the above. Any link on the web

I doubt there is any central directory. You will probably have to
look up the documentation on each compiler separately. Then again,
if you are going to use these, it should be to exploit the compiler
extensions, so you'll have to read the documentation anyway.
 
G

Goran Larsson

sathya_me said:
If the preprocessor finds the specific condition it prints the message
and exits.

There is nothing in the given source code that makes the "preprocessor"
print anything or makes the "preprocessor" exit.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top