473,699 Members | 2,715 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Predefined macro namespace

I've been trying to track down explicit information about this for some time.

I know that the ANSI C standard specifies the __* and _[A-Z]* macro
namespace as reserved for the compiler implementation, and playing with
a handful of compilers I can find what those specific compilers predefine,
but is there any information out there on how that reserved namespace
should be used?

If I am writing some portable code what predefined macros should I expect
to tell me what the compiler is targetting? I've seen almost random
collections of things like __win__ __WIN32__ __WIN __DOS__ __MSDOS__ __unix
__HPIX__ _M68000_ __M68000__ _M68K_ etc.

If I write a fancy new implementation to target a Bambleweeny 57 Sub-Meson
Brain what macros should I make my compiler predefine? Should I predefine
__TEA__, __tea__ or __hottea__ for the targetted i/o system and should the
datastore be __BROWN__ or __brown__ etc????

Thanks

--
JGH - www.mdfs.net
Nov 13 '05 #1
6 2713
J.G.Harston wrote:
I've been trying to track down explicit information about this for some time.

I know that the ANSI C standard specifies the __* and _[A-Z]* macro
namespace as reserved for the compiler implementation, and playing with
a handful of compilers I can find what those specific compilers predefine,
but is there any information out there on how that reserved namespace
should be used?

If I am writing some portable code what predefined macros should I expect
to tell me what the compiler is targetting? I've seen almost random
collections of things like __win__ __WIN32__ __WIN __DOS__ __MSDOS__ __unix
__HPIX__ _M68000_ __M68000__ _M68K_ etc.
I suppose there's more than one possible meaning for "portable", but I
wouldn't consider code that relies on compiler-specific predefined
macros to be portable. "Portable", at least by my definition, means that
the code will work on any implementation, so there would be no reason to
hide parts of it using preprocessor conditionals.

If I write a fancy new implementation to target a Bambleweeny 57 Sub-Meson
Brain what macros should I make my compiler predefine? Should I predefine
__TEA__, __tea__ or __hottea__ for the targetted i/o system and should the
datastore be __BROWN__ or __brown__ etc????


There is no good, topical answer to your question. These things are
inherently implementation-defined. To the best of my knowledge, the
standard makes no recommendations or requirements aside from what you've
already mentioned.

Personally, I despise #ifdef-riddled code and avoid it at all costs. I'd
recommend using alternative source files for different targets instead.
For example, suppose I have a module called coolstuff.c. Maybe this is a
generic, purely ISO C implementation, but not very efficient. I can make
a more efficient implementation for a particular platform by using
system-specific libraries. So I might create coolstuff_sparc .c,
coolstuff_x86.c , coolstuff_mips. c, etc. Then I compile and link against
whichever is most appropriate for the platform I'm compiling for.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Nov 13 '05 #2
In article <QO************ *@newsread1.new s.pas.earthlink .net>,
us************* ********@neverb ox.com says...
If I am writing some portable code what predefined macros should I expect
to tell me what the compiler is targetting? I've seen almost random
collections of things like __win__ __WIN32__ __WIN __DOS__ __MSDOS__ __unix
__HPIX__ _M68000_ __M68000__ _M68K_ etc.
I suppose there's more than one possible meaning for "portable", but I
wouldn't consider code that relies on compiler-specific predefined
macros to be portable.


How about "ported"? I.e., in order to get certain types of programs
working on more than one platform, you MUST do platform-dependant things,
then add modules to support each platform that differs from one previously
implemented. That does not mean that 99% of the source can't be
completely free of such, and the remaining 1% requires attention when
adding a new platform not previously tested. I'd suggest that the above
scenario is far better than what is commonly encountered when attempting
to move source to a new platform.
"Portable", at least by my definition, means that
the code will work on any implementation, so there would be no reason to
hide parts of it using preprocessor conditionals.
Such code is very limited by the confines of the standard C "sandbox".
Personally, I despise #ifdef-riddled code and avoid it at all costs. I'd
recommend using alternative source files for different targets instead.
For example, suppose I have a module called coolstuff.c. Maybe this is a
generic, purely ISO C implementation, but not very efficient. I can make
a more efficient implementation for a particular platform by using
system-specific libraries. So I might create coolstuff_sparc .c,
coolstuff_x86.c , coolstuff_mips. c, etc. Then I compile and link against
whichever is most appropriate for the platform I'm compiling for.


This is a great solution in cases where the implementations are
dramatically different. On some things though, the only difference
between two platforms might be the header to be included, or a three lines
of initialization code followed by the rest of it being identical. I
don't see a point in having two copies of the source file with the only
difference being trivial. That just makes maintenance a nightmare.

IOW, there is no one-size-fits-all answer and blanket statements about
the "one true way" are typically incorrect under examination.

--
Randy Howard _o
2reply remove FOOBAR \<,
_______________ _______()/ ()_____________ _______________ _______________ ___
SCO Spam-magnet: po********@sco. com
Nov 13 '05 #3
Randy Howard wrote:
In article <QO************ *@newsread1.new s.pas.earthlink .net>,
us************* ********@neverb ox.com says...

<snip>
"Portable", at least by my definition, means that
the code will work on any implementation, so there would be no reason to
hide parts of it using preprocessor conditionals.

Such code is very limited by the confines of the standard C "sandbox".


True. There seems to be 3 different categories of things you might want
to do in a C program: 1) Things that can be done well in straight C. 2)
Things that can be done, though somewhat poorly, in straight C. 3)
Things that simply cannot be done without extensions.

My thinking at the moment is that you could isolate those parts that
fall into categories 2 and 3, and provide implementations that work as
well as possible. For 2, this would mean that they use the
unsatisfactory but standard methods. For 3 I'm thinking that you could
abort with a diagnostic ("not implemented yet"), continue with a
diagnostic, or fail to compile, and choose which of these should occur
based on configuration option.

Personally, I despise #ifdef-riddled code and avoid it at all costs. I'd
recommend using alternative source files for different targets instead.
For example, suppose I have a module called coolstuff.c. Maybe this is a
generic, purely ISO C implementation, but not very efficient. I can make
a more efficient implementation for a particular platform by using
system-specific libraries. So I might create coolstuff_sparc .c,
coolstuff_x86 .c, coolstuff_mips. c, etc. Then I compile and link against
whichever is most appropriate for the platform I'm compiling for.

This is a great solution in cases where the implementations are
dramatically different. On some things though, the only difference
between two platforms might be the header to be included, or a three lines
of initialization code followed by the rest of it being identical. I
don't see a point in having two copies of the source file with the only
difference being trivial. That just makes maintenance a nightmare.


I completely agree. That would be a disaster. Maintaining separate
nearly identical sources is a very bad idea. I'm talking somewhat
theoretically here, because I don't have much experience writing
portable code that requires a lot of non-standard extensions. I did use
a technique like this with a great deal of success a while back, while
writing networking layer that was initially intended to run on a
8051-based single-board computer, and on a PC for testing purposes (it's
much easier to test on a PC). I was surprised at how well this worked. I
didn't even bother to compile or test on the 8051 until after it was up
and running on the PC. I expected it to take up to a week to get it
running on the 8051. It took about half a day.

Even so, in hindsight I don't feel that I took exactly the right
approach. Basically I defined a set of "primitive" functions that would
have to be re-implemented for each target. These functions were very
low-level. Now I think that they were *too* low-level. Because of that,
they were quite easy to implement for a new target (because each did a
single, simple task), but they didn't really create an ideal interface.
The main system was uglier because it had to use an interface that was,
for lack of a better word, unnatural. In retrospect, I definitely should
have made the interface a higher priority.

Getting back to the main topic, your point is well taken. But even so, I
would avoid lines of code that look like this:

#if defined(__SYSTE M_A__)
DoInitStep1();
DoInitStep2();
DoInitStep3();
#elif defined(__SYSTE M_B__)
do_B_init();
#endif

/* 500 common lines follow */

Init() may be a candidate for a target-specific function, though it
would be very short in some cases, and it may not fit well in any
existing target-specific source file. Obviously creating a new source
file for every trivial thing that doesn't fit somewhere else could get
ridiculous.

Another option is to define Init conditionally:

#if defined(__SYSTE M_A__)
# define Init() do { DoInitStep1(); DoInitStep2(); \
DoInitStep3(); } while (0)
#elif defined(__SYSTE M_B__)
# define Init() do_B_init()
#endif

The advantage here is that, while it's still ugly, the ugliness is
isolated from the main part of the source, thus leaving the part that
does the real work a bit less cluttered. If Init() is going to be used
in more than one place, then this might prevent a lot of ugliness.

Finally, another alternative might be to factor out the commonality and
have some sources that are target-specific, but shared between some
similar targets.

IOW, there is no one-size-fits-all answer and blanket statements about
the "one true way" are typically incorrect under examination.


Yes, but there are more- and less-preferable methods. Personally I see
avoiding code with a lot of #ifdefs as a good goal, but, as always,
there are many things to consider and it may be that a #ifdef is the
best choice (or the least bad choice).

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Nov 13 '05 #4
Kevin Goodsell wrote:

I suppose there's more than one possible meaning for "portable", but I
wouldn't consider code that relies on compiler-specific predefined
macros to be portable. "Portable", at least by my definition, means that
the code will work on any implementation, so there would be no reason to
hide parts of it using preprocessor conditionals.


#include <stdio.h>
#include <limits.h>
#if INT_MAX >= 1000000
#define MILLION_FMT "d"
#else
#define MILLION_FMT "ld"
#endif

int main(void) {
printf ("For the %" MILLION_FMT "th time, Hello world!\n",
1000000);
return 0;
}

Any portability problems?

--
Er*********@sun .com
Nov 13 '05 #5
Eric Sosman wrote:
Kevin Goodsell wrote:
I suppose there's more than one possible meaning for "portable", but I
wouldn't consider code that relies on compiler-specific predefined
macros to be portable. "Portable", at least by my definition, means that
the code will work on any implementation, so there would be no reason to
hide parts of it using preprocessor conditionals.

#include <stdio.h>
#include <limits.h>
#if INT_MAX >= 1000000
#define MILLION_FMT "d"
#else
#define MILLION_FMT "ld"
#endif

int main(void) {
printf ("For the %" MILLION_FMT "th time, Hello world!\n",
1000000);
return 0;
}

Any portability problems?


Not that I can see, but it also doesn't use the type of macros I was
talking about. My last sentence above isn't as clear as it should have
been, but the first sentence mentions "compiler-specific predefined
macros", by which I meant things like __GNU_C__ and __MSVC_VER (or
however they are actually spelled).

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Nov 13 '05 #6
In <3F************ ***@sun.com> Eric Sosman <Er*********@su n.com> writes:
Kevin Goodsell wrote:

I suppose there's more than one possible meaning for "portable", but I
wouldn't consider code that relies on compiler-specific predefined
macros to be portable. "Portable", at least by my definition, means that
the code will work on any implementation, so there would be no reason to
hide parts of it using preprocessor conditionals.


#include <stdio.h>
#include <limits.h>
#if INT_MAX >= 1000000
#define MILLION_FMT "d"
#else
#define MILLION_FMT "ld"
#endif

int main(void) {
printf ("For the %" MILLION_FMT "th time, Hello world!\n",
1000000);
return 0;
}

Any portability problems?


No, but you're actually making his point. The code can be rewritten in
a much more readable fashion with no loss of portability:

#include <stdio.h>

int main(void) {
printf("For the %ldth time, Hello world!\n", 1000000L);
return 0;
}

Your example also shows that not being able to rely on a given type for
a given purpose destroys the code readability. If hardcoded long is
not an option for your example, it may be worth considering a trade
off between portability to obscure platforms and readable code:

#include <stdio.h>
#include <limits.h>
#if INT_MAX < 1000000
#error "This program requires a wider int"
#endif

int main(void) {
printf("For the %dth time, Hello world!\n", 1000000);
return 0;
}

Such a trade off was probably out of question 15 years ago, but times have
changed...

Programming is more a matter of making the right choices than of following
the "right" religion.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #7

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

Similar topics

20
2824
by: Dead RAM | last post by:
Hey people, i'll try to keep this short ;) Here is what I want to type (or at least close too)... #define VER_BUILD 1 #define STR_VER_BUILD "VER_BUILD" But what happends is the preprocessor see the quots in STR_VER_BUILD and replaces that text with "VER_BUILD"... I need it to see the VER_BUILD and replace it with 1, and only after doing
6
1873
by: marco_segurini | last post by:
Hi, I like to know if this is a good way to remove 'line 18' from compilation when DBG is not defined (I dislike to wrap 'line 18' using #if/#endif pair) of if there are better ways (always using the namespace). Am I sure that the compiler generates non code for 'line 18'? /////////////////////////
6
7179
by: cody | last post by:
where can i find a list of all predefined preprocessor macros in c#? i searched in the msdn but i can't find it. i now there is at lest one: DEBUG. but what else? -- cody www.deutronium.de.vu || www.deutronium.tk
5
4149
by: sathya_me | last post by:
friends, Please go through the following code which I have downloaded from Bob Stout (Snippets): #include <stdio.h>
0
1197
by: Chris Ellis | last post by:
Hi, I'm trying to write a macro that will generate managed c++ wrappers of map. I want a managed iterator and a managed map. I successfully built a pair of classes (iterator and map) that work fine. I called it IntToIntMap and IntToIntIterator. When I was finished, I realized that if I ever wanted to map two other data types, I would have to do just as much work, so I decided to make a macro to fake templating. So, I modeled the...
3
2005
by: casul | last post by:
Hi All, I was told there were a few macro gurus on this group :) I'm trying to define a macro that will allow me to write the following code : #include MY_MACRO( NAME, SPACE )
3
1790
by: NickP | last post by:
Hi there, I am trying to do a reflection only load of an assembly, within a new appdomain, within a macro. i.e. create new app domain instantiate class run class
2
1843
by: utab | last post by:
Dear all, I was looking at a simple code on an exercise question. In the code, there is a conditional inclusion dependent on __GNUC__ #include <algorithm> #include <iomanip> #ifndef __GNUC__ #include <ios> #endif
1
1183
by: rk | last post by:
Is there a predefined macro set when the TR1 extensions from the "Visual C++ 2008 feature pack" are installed? Thanks rk
0
8613
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9172
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9032
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
7745
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6532
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5869
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4374
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3054
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2008
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.