473,748 Members | 3,697 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Conditional compilation sans the cpp

I've made no secret of the fact that I really dislike the C preprocessor in
C++. No aspect of the language has caused me more trouble. No aspect of
the language has cause more code I've read to be difficult to understand.
I've described it as GOTO's on steroids, and that's what it is!.

One argument against abolishing it it that it is useful for conditional
compilation when porting code, etc. Well, it seems to me C++ supports that
natively. According to TC++PL(SE) §24.3.7.2 if a block of code is
bracketted with an if(CONDITION){. ..} the entire expression is "compiled
away" when CONDITION==fals e.

Can this not be used in place of the typical #ifdef ... #endif used for
conditional compilation?
--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #1
11 2468
Steven T. Hatton wrote:
I've made no secret of the fact that I really dislike the C preprocessor
in
C++. No aspect of the language has caused me more trouble. No aspect of
the language has cause more code I've read to be difficult to understand.
I've described it as GOTO's on steroids, and that's what it is!.

One argument against abolishing it it that it is useful for conditional
compilation when porting code, etc. Well, it seems to me C++ supports
that
natively. According to TC++PL(SE) §24.3.7.2 if a block of code is
bracketted with an if(CONDITION){. ..} the entire expression is "compiled
away" when CONDITION==fals e.

Can this not be used in place of the typical #ifdef ... #endif used for
conditional compilation?


This will work in many places, however, there are some instances where your
idea would not work, namely when the code is not within the body of a
function:

(a) the preprocessor allows you to conditionally include files.
(b) it allows to change the signature of a function.
(c) it allows to include or exclude certain members in a class.

Probably, there is way more.
Best

Kai-Uwe Bux
Jul 22 '05 #2


Steven T. Hatton wrote:
I've made no secret of the fact that I really dislike the C preprocessor in
C++. No aspect of the language has caused me more trouble. No aspect of
the language has cause more code I've read to be difficult to understand.
I've described it as GOTO's on steroids, and that's what it is!.

One argument against abolishing it it that it is useful for conditional
compilation when porting code, etc. Well, it seems to me C++ supports that
natively. According to TC++PL(SE) §24.3.7.2 if a block of code is
bracketted with an if(CONDITION){. ..} the entire expression is "compiled
away" when CONDITION==fals e.

Can this not be used in place of the typical #ifdef ... #endif used for
conditional compilation?


#ifdef DEVELOPMENT
#ifdef USE_DEBUG
#define DEBUG_FUNC(FUNC ) FUNC
#else
#define DEBUG_FUNC(FUNC )
#endif
#endif

int sort(class Collection& col, sortType type)
{
// sort the collection some how
...

DEBUG_FUNC(chec k_sorted(col,ty pe));
}

is less clutter than:

int sort(class Collection& col, sortType type)
{
// sort the collection some how
...

if (DEBUG_FUNC) {
check_sorted(co l,type);
}
}

and you still have the problem of how to get the compiler to know that
DEBUG_FUNC is always false?

Then there is also <cassert> or your favourite replacement.
Jul 22 '05 #3
"Steven T. Hatton" wrote:

I've made no secret of the fact that I really dislike the C preprocessor in
C++. No aspect of the language has caused me more trouble. No aspect of
the language has cause more code I've read to be difficult to understand.
I've described it as GOTO's on steroids, and that's what it is!.

One argument against abolishing it it that it is useful for conditional
compilation when porting code, etc. Well, it seems to me C++ supports that
natively. According to TC++PL(SE) §24.3.7.2 if a block of code is
bracketted with an if(CONDITION){. ..} the entire expression is "compiled
away" when CONDITION==fals e.
But it nevertheless runs through the compiler.

Can this not be used in place of the typical #ifdef ... #endif used for
conditional compilation?


Not in all cases.

Consider:
You want to write a function that deals with directories. On one
system the calls for this are callled eg. GetFirstFile, GetNextFile.
On another system the very same calls are called eg. GetFirst, GetNext.
On a third system the whole mechanism works in a complete different
way.
So the point is here: While on system A there are functions GetFirstFile and
GetNextFile, those functions aren't even available on system B or system C. So
you need a way to 'hide' those function calls from the compiler.

#ifdef SYSTEM_A

i = GetFirstFile( Directory );
while( i ) {
i = GetNextFile( FileName );
Process( FileName );
}

#else if SYSTEM_B

i = GetFirst( Directory );
while( i ) {
i = GetNext( FileName );
Process( FileName );
}

#else if SYSTEM_C

ReadDirectory( Directory, DirStruct );
for( i = 0; i < DirStruct.NrEnt ries; ++ i )
Process( DirStruct( File[i] );

#endif

When compiling for SYSTEM_A you actually need the compiler to not even
*see* the code for implementations in SYSTEM_B or SYSTEM_C, since SYSTEM_A
simple doesn't have that functions available.

--
Karl Heinz Buchegger
kb******@gascad .at
Jul 22 '05 #4
lilburne wrote:
int sort(class Collection& col, sortType type)
{
// sort the collection some how
...

DEBUG_FUNC(chec k_sorted(col,ty pe));
}

is less clutter than:

int sort(class Collection& col, sortType type)
{
// sort the collection some how
...

if (DEBUG_FUNC) {
check_sorted(co l,type);
}
This form is more consitant with C++, more immediately intelligible, and
doesn't require the code to be modified behind my back. If you are really
concerned about clutter you could do this:

if (DEBUG_FUNC) {check_sorted(c ol,type);}

Or depending on its return type:

if (DEBUG_FUNC && check_sorted(co l, type){}
and you still have the problem of how to get the compiler to know that
DEBUG_FUNC is always false?
const DEBUG_FUNC=fals e;
Then there is also <cassert> or your favourite replacement.


I'm not really sure why I need those. What does assert give me that I can't
get from native C++? If the sensible thing were done, there would be a way
to deterministicly resolve names in progams to declarations and definitions
in libraries as needed without the use of header files. Such a mechanism
could be used to locate the definition of DEBUG_FUNC whereever it may be
relative to the code you are compiling. I'm assuming it is a C++ constant,
and not a macro mangle. But as a general rule, I dislike the use of
globals. Be they functions, classes, variables, or constants. I would not
want to encourage such proactices as a general means of changing the
character of a program.

I really wish someone with the power to influence what goes into the
Standard would identify a means to accomplish the few things of value that
the cpp provides in a way that is more deterministic, coherent and
deterministic.

I've come to believe the greatest advantage Java has over C++ regarding ease
of use is not introspection, not garbage collection, not the elimination of
user manipulated pointers, not the restriction against using assignment as
a boolean condition, not the lack of MI, not the simpler and more uniform
syntax, not the extensive set of easy to use libraries. What Java has
over C++ is that it doesn't use the CPP. And it has, hands down, a better
exception handling mechanism. It is simply too hard to build tools that
can evaluate your code in the context of your development environment with
the incoherence introduced by the CPP.

Stroustrup's comment in §24.3.7.2 regarding the use of NDEBUG in conjunction
with /assert/ is: "Like all macro magic, this use of NDEBUG is too
low-level, messy, and error-prone.

A simple example of what is fundamentally wrong with C++'s reliance on the
#include <header> approach is when I tried using /size_t/ in a translation
unit that didn't #include anything else from the Standard Library. It was
undefined. The way I found it was to look it up in ISO/IEC 14882:2003 and
discovered it is defined in #include <cstddef>. The fact that /size_t/ had
always been available without my #including <cstddef> means there are
multiple paths through the headers that can result in such identifiers
being introduced into my code silently. That is a bad thing. It leads to
dependencies on things I am not aware of. THAT DOESN'T SCALE!
--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #5


Steven T. Hatton wrote:
lilburne wrote:

int sort(class Collection& col, sortType type)
{
// sort the collection some how
...

DEBUG_FUNC(chec k_sorted(col,ty pe));
}

is less clutter than:

int sort(class Collection& col, sortType type)
{
// sort the collection some how
...

if (DEBUG_FUNC) {
check_sorted(co l,type);
}

This form is more consitant with C++, more immediately intelligible, and
doesn't require the code to be modified behind my back. If you are really
concerned about clutter you could do this:

if (DEBUG_FUNC) {check_sorted(c ol,type);}

Or depending on its return type:

if (DEBUG_FUNC && check_sorted(co l, type){}

To say that the rewrite you habe given reduces clutter you can't have
had the privilege of looking at functions that have these
DEBUG_FUNC(...) statements every two or three lines.

and you still have the problem of how to get the compiler to know that
DEBUG_FUNC is always false?

const DEBUG_FUNC=fals e;


How do you get that into the program? By having different headers, or by
editing a header? If the former how do you choose between the headers?
If the later how do you deal with the recompilation of 100s of source files?

Then there is also <cassert> or your favourite replacement.

I'm not really sure why I need those. What does assert give me that I can't
get from native C++?


Earlier you were discussing rectangles and points. The nearest thing we
have is a 3d box. This is the code for returning what we consider the
maximum point of a 3d box, which is pretty typical of our 'one-line'
functions:

Point3D Box3D::max() const
{
ASSERT_STATE(!i nvalid(),"Box3D ::max");
ASSERT_STATE(m_ arr[1][0] < infinity(),"Box 3D::max | infinite");
ASSERT_STATE(m_ arr[1][1] < infinity(),"Box 3D::max | infinite");
ASSERT_STATE(m_ arr[1][2] < infinity(),"Box 3D::max | infinite");)
return Point3D(m_arr[1][0],m_arr[1][1],m_arr[1][2]);
}


Stroustrup's comment in §24.3.7.2 regarding the use of NDEBUG in conjunction
with /assert/ is: "Like all macro magic, this use of NDEBUG is too
low-level, messy, and error-prone.

Anyone not using /assert/ has messy, error-prone code.

A simple example of what is fundamentally wrong with C++'s reliance on the
#include <header> approach is when I tried using /size_t/ in a translation
unit that didn't #include anything else from the Standard Library. It was
undefined. The way I found it was to look it up in ISO/IEC 14882:2003 and
discovered it is defined in #include <cstddef>. The fact that /size_t/ had
always been available without my #including <cstddef> means there are
multiple paths through the headers that can result in such identifiers
being introduced into my code silently. That is a bad thing. It leads to
dependencies on things I am not aware of. THAT DOESN'T SCALE!

Well there are many projects applications that contain 1,000,000s of
lines of code. The application I work on has about 10,000,000. Defines
in header files and conditional compilations really aren't a problem.

Jul 22 '05 #6
Karl Heinz Buchegger wrote:
"Steven T. Hatton" wrote:

I've made no secret of the fact that I really dislike the C preprocessor
in
C++. No aspect of the language has caused me more trouble. No aspect of
the language has cause more code I've read to be difficult to understand.
I've described it as GOTO's on steroids, and that's what it is!.

One argument against abolishing it it that it is useful for conditional
compilation when porting code, etc. Well, it seems to me C++ supports
that
natively. According to TC++PL(SE) §24.3.7.2 if a block of code is
bracketted with an if(CONDITION){. ..} the entire expression is "compiled
away" when CONDITION==fals e.


But it nevertheless runs through the compiler.

It would appear that is the case with g++. I doesn't simply ignore
unreachable code. I know Stroustrup and some others have been playing with
a design for some kind of macro firewall that is supposed to isolate code
from an effects from the preprocessor. But that can't be completely
effective. The CPP is capable of rewriting any code not exclusively
protected, and if you depend on any of the stuff it mangles, all bets are
off.

I fully understand that the CPP has been used to to some great stuff. The
damn thing's been around since the mid 70s or so. It couldn't have
survived this long if it wasn't useful. I probably have most of my major
problems with understanding what it's doing to me under normal
circumstances behind me. OTOH, if Stroustrup has been stung by other
people's macros mangling his code, I'm sure it can and will happen to a
mere mortal like me.

Not only that, but take a look at a translation unit some time. I was in
shock when I saw everything the CPP sucked in to build a tiny little file.
There's got to be a better way!

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #7
"Steven T. Hatton" wrote:

I fully understand that the CPP has been used to to some great stuff. The
damn thing's been around since the mid 70s or so. It couldn't have
survived this long if it wasn't useful. I probably have most of my major
problems with understanding what it's doing to me under normal
circumstances behind me.


My understanding is this:
The CPP is nothing else then a glorified text editor that runs before
the actual compiler even sees the source code. The tricky thing is:
The text editor is controlled by a programming language and the tricky
part is that the statements of that programming language are embedded
in the text to edit itself.

--
Karl Heinz Buchegger
kb******@gascad .at
Jul 22 '05 #8
"Steven T. Hatton" <su******@setid ava.kushan.aa> wrote:
One argument against abolishing it it that it is useful for conditional
compilation when porting code, etc. Well, it seems to me C++ supports that
natively. According to TC++PL(SE) §24.3.7.2 if a block of code is
bracketted with an if(CONDITION){. ..} the entire expression is "compiled
away" when CONDITION==fals e.


However, the body of the function is still analysed for correctness,
i.e. it just an optimization not really conditional compilation. To some
extend you can use template for conditional compilation: a template which
is not instantiated is not checked for correctness to some degree.
--
<mailto:di***** ******@yahoo.co m> <http://www.dietmar-kuehl.de/>
<http://www.contendix.c om> - Software Development & Consulting
Jul 22 '05 #9
lilburne wrote:


Steven T. Hatton wrote:
lilburne wrote:


Well there are many projects applications that contain 1,000,000s of
lines of code. The application I work on has about 10,000,000. Defines
in header files and conditional compilations really aren't a problem.


On large programs that have produce many combinations, the
defines become a large problem. I've worked on projects
where the OS command line was not large enough to support
all the #defines.

I prefer using standard interfaces and letting the linker
or build script choose which source file to implement
the interface with.

For example, my project at work as a lot of
#ifdef PLATFORM_IS_BIG _ENDIAN
#else
#endif
for converting message fields to the native byte ordering.

I would rather have a single function:
value = Apply_Endian_Co nversion(old_va lue);
and have different implementations that the build
script chooses. IMHO, this technique provides cleaner
code (easier to read) and fewer compilation and
porting problems.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.l earn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book

Jul 22 '05 #10

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

Similar topics

2
4320
by: Steve Jorgensen | last post by:
To begin with an example... Let's say you were wanting to write code usign early binding to the MSXML library, but then be able to switch between early and late binding at will. Conditional compilation is one possibility, but it's not practical. 1. You have to put a precompiler condition block around every Dim and every function declaration that might need to change, 2. If the code spans multiple modules, the flags have to be changed...
1
16559
by: chris han | last post by:
Hi, all, I'm trying to use Conditional Compilation Statements in my code. using System; #define DEBUG public class MyClass { public static void Main() {
12
2500
by: wanghz | last post by:
Hi, Could I ask some questions about the conditional compilaion? Suppose I have three simple files: a.c, b.c and c.h /* --------a.c--------- */ #include <stdio.h> #include "c.h" int main()
2
2586
by: FireStarter | last post by:
Guys, in the code that follows, why does the method F() still compile, even if DBG is undefined? Inside method G(), the code inside <#if DBG> does not compile (notice that I can write whatever I want in there, I will not receive a compilation error). I do get such an error in F() - because of the garbage I intentionally put there - but F() should not compile in the first place. Am I misusing this attribute?! #undef DBG
1
3326
by: A.M-SG | last post by:
Hi, We have a solution with several c# projects within it. How can I define solution wide conditional compilation symbols?
1
1602
by: lavu | last post by:
Is there any way to specify a different executable name for my project based on value that I have set in my conditional compilation constant. For eg: If I have FIRST specified in my conditional compilation constant then I would like the executable to be XYZ.exe and if nothing is specified then the executable should be ABC.exe. Any ideas appreciated. Thanks in advance.
4
2798
by: Bob | last post by:
Hi, In VS2003 conditional compilation constants and their state could be defined at project level. I was using this to control what features where offered by various builds. i.e. Feature1=true,Feature2=false, ... VS2005 seems to either allow the existance of the constant or not. ie. You must omit a constant not declare it to be false This means that the list no longer declares the state of all the options.
10
3094
by: Dave | last post by:
I'm a C++ programmer of many years, trying to get my feet wet in C#. I have a question about conditional compilation. In C++, I would sometimes define a constant in an include file, and then have blocks of code in different source files that were conditionally compiled based on that constant. Now that C# has done away with include files, is there any way of doing the same thing, short of defining the constant multiple times at the head...
6
2851
by: maxwell | last post by:
I'm trying to use the gpp utility (Gnu points to http://en.nothingisreal.com/wiki/GPP) to do conditional compilation in Python, and I'm running into a problem: the same '#' character introduces Python comments and is used by default to introduce #ifdef etc. lines. Here's an example of what I'm trying to do: #ifdef DEBUG stderr.write("variable is...") #details of msg omitted #endif
0
8989
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8828
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
9537
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...
1
9319
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9243
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6073
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
4869
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3309
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
2
2780
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.