Thoughts on #ifdef, #define statements - I am not a fan of recursive includes

I am not a big fan of the C/C++ preprocessor directives #ifdef or #ifndef. I 
am not denying that they certainly have their place and usage in the 
language. I'll first write about where I think they are useful and then 
about the situations where I feel they are not. #ifndef is very useful for 
preventing multiple inclusions of a header which will cause redefinition 
errors.

#ifndef __FOO_H__ // only proceed if the token is not yet defined
#define __FOO_H__ // define the token so that subsequent includes have it 
defined
[...contents of the header...]
#endif // __FOO_H__, end for #ifndef statement

Of course, you can use #pragma once to do the same thing, but that is a 
Vendor-specific extension to the language (in my case Microchip MCU 
Controllers, PIC18F5420) so not everyone will use it. But this usage is 
error prone - I can't count the number of times that I copied one header to 
create another header in the same project and forgot to change the #ifndef 
token to a new token and couldn't figure out why my new header wasn't being 
evaluated properly.

#ifdef is useful in a header to switch between ANSI and wide versions of the 
function, such as this example from winbase.h:

#ifdef UNICODE
#define CreateFile  CreateFileW
#else
#define CreateFile  CreateFileA
#endif // !UNICODE
Now, the reason I don't like these 2 directives is that they behave 
differently then #if token or #if !token. #if token evaluates the value of 
token. If token is not defined, it defaults to zero and the #if token 
phrases evaluates to zero. On the other hand, #ifdef token evaluates to 
token to see if it is defined, regardless of the value of token. That means 
that the following code

#define FOO 0x0

#ifdef FOO
printf("FOO!");
#else
printf("NOT FOO!");
#endif
will print out "FOO!" even though FOO evaluates to zero. As I have written 
previously in my blog and in the newsgroups, I am big on maintainance of the 
code I write because the code I write will have to be maintained for years 
and its connection to me will eventually be lost by the developer who 
inherits it. What I don't like about #ifdef/ifndef in a source file (vs the 
header file examples above) is that at first glance, I mentally evaluate a 
#ifdef as a #if and more often then not, pick the wrong result when 
reviewing the code. Furthermore, everytime I see #ifndef I need to spend a 
minute or two staring at the entire statement to figure out what is going 
on, it is not immediately apparent to me what it is doing. Anytime I have to 
stare at something to figure out what it does, it is an indicator to me that 
others will probably do the same and it will eventually be a problem spot in 
the code in the future.
A lot of you may not agree with me and I am fine with that ;). Please let me 
know why though.

Stan Starinski 

0
Stan
12/29/2009 11:52:20 PM
windows.vista.general 2096 articles. 0 followers. Follow

1 Replies
633 Views

Similar Articles

[PageSpeed] 56

You should really think about contacting your psychiatrist and asking for a 
correction to the dosage of medicine your are taking.

Just FYI.


"Stan Starinski" <China@stealsUSJobsPatentsSoftwareMusicVideo> wrote in 
message news:OzcjvHOiKHA.4220@TK2MSFTNGP05.phx.gbl...
> I am not a big fan of the C/C++ preprocessor directives #ifdef or #ifndef. 
> I am not denying that they certainly have their place and usage in the 
> language. I'll first write about where I think they are useful and then 
> about the situations where I feel they are not. #ifndef is very useful for 
> preventing multiple inclusions of a header which will cause redefinition 
> errors.
>
> #ifndef __FOO_H__ // only proceed if the token is not yet defined
> #define __FOO_H__ // define the token so that subsequent includes have it 
> defined
> [...contents of the header...]
> #endif // __FOO_H__, end for #ifndef statement
>
> Of course, you can use #pragma once to do the same thing, but that is a 
> Vendor-specific extension to the language (in my case Microchip MCU 
> Controllers, PIC18F5420) so not everyone will use it. But this usage is 
> error prone - I can't count the number of times that I copied one header 
> to create another header in the same project and forgot to change the 
> #ifndef token to a new token and couldn't figure out why my new header 
> wasn't being evaluated properly.
>
> #ifdef is useful in a header to switch between ANSI and wide versions of 
> the function, such as this example from winbase.h:
>
> #ifdef UNICODE
> #define CreateFile  CreateFileW
> #else
> #define CreateFile  CreateFileA
> #endif // !UNICODE
> Now, the reason I don't like these 2 directives is that they behave 
> differently then #if token or #if !token. #if token evaluates the value of 
> token. If token is not defined, it defaults to zero and the #if token 
> phrases evaluates to zero. On the other hand, #ifdef token evaluates to 
> token to see if it is defined, regardless of the value of token. That 
> means that the following code
>
> #define FOO 0x0
>
> #ifdef FOO
> printf("FOO!");
> #else
> printf("NOT FOO!");
> #endif
> will print out "FOO!" even though FOO evaluates to zero. As I have written 
> previously in my blog and in the newsgroups, I am big on maintainance of 
> the code I write because the code I write will have to be maintained for 
> years and its connection to me will eventually be lost by the developer 
> who inherits it. What I don't like about #ifdef/ifndef in a source file 
> (vs the header file examples above) is that at first glance, I mentally 
> evaluate a #ifdef as a #if and more often then not, pick the wrong result 
> when reviewing the code. Furthermore, everytime I see #ifndef I need to 
> spend a minute or two staring at the entire statement to figure out what 
> is going on, it is not immediately apparent to me what it is doing. 
> Anytime I have to stare at something to figure out what it does, it is an 
> indicator to me that others will probably do the same and it will 
> eventually be a problem spot in the code in the future.
> A lot of you may not agree with me and I am fine with that ;). Please let 
> me know why though.
>
> Stan Starinski 

0
Bill
12/30/2009 4:27:14 PM
Reply:

Similar Artilces:

Time Calculations / If Statements
I am needing to do a calculation on time results, however, when my time difference involves results from times of 2400 and greater, my result is inaccurate. See below: F1 G1 ATA ETA 2400 0015 (formula: f1-g1) answer is: 2385, but should be 15. 2400 is midnight, 0015 is 12:15. I can't figure out how to enter formula so I can calculate difference in late arrivals when it's midnight. Would an "if"statement fix this, if so, how do you do that? Or how do I fix this problem? Your help would be GREATLY APPRECIATED! :) Anita, use =MOD(end-start,1) -- Regard...

IF statement #8
is there a way to say to create a column that displays a Yes or No if part of a field has some text in it for example if you wanted to tag the ones that had a D in column A ColumnA Tag abc N abde Y abcd Y Thanks! =LEN(A1)<>LEN(SUBSTITUTE(A1,"d","")) ......................... TRUE/FALSE =IF(LEN(A1)<>LEN(SUBSTITUTE(A1,"d","")),"Y","N") .......... Y/N best wishes -- Bernard V Liengme Microsoft Excel MVP http://people.stfx.ca/bliengme remove caps from ...

Error of "application-defined or object-defined error" in Goalseek
Hi all, I always have above error while running below code in the excel 2007, please help me out! Sub GoalSeekTry() Source = Cells(8, 7) x = Cells(7, 7).Value ActiveSheet.Range(Source).GoalSeek Goal:=-800, ChangingCell:=ActiveSheet.Range(x) End With End Sub Source = X*X +X*300 Regards, Edward sorry adjust the code little bit by removing "End With" Sub GoalSeekTry() Source = Cells(8, 7) x = Cells(7, 7).Value ActiveSheet.Range(Source).GoalSeek Goal:=-800, ChangingCell:=ActiveSheet.Range(x) End Sub "Edward Wang" wrote: > Hi all, > I...

Hourly Sales Totals including Taxes
Can anybody provide me with an hourly sales report that includes taxes? There is an hourly sales report available in the reports section at customersource but it doesn't include tax(es). Also if this report could be chronologically sorted that would even be better (right now it shows 10:00, 11:00 etc before 7:00, 8:00 etc) Thank you, Dear Alex, let me know which report you are talking can you send me this report on alwani89@hotmail.com also yes it is possible to customize the report whatever way you want. Regards "Alex" wrote: > Can anybody provide me with an hou...

Writing Formulas to Include All Rows in Worksheet
What is the proper technique for writing a formula that includes all rows in a worksheet? The number of rows in the worksheet change frequently. So, for example, if I wanted to sum all of the rows from A1 through A1000 today, but A1 through A1100 tomorrow (because of new rows added), I would have to update my formula to include the new rows. I could write my formulas to include rows with no data in them (e.g., =SUM(A1:A1048576)), but is there a better way to write a formula that automatically "expands" as new rows are added? Thank you in advance, -- Sean =SUM(A:A) -- ...

SOP Statements
Hello, We are using GP v 9.0. I have just recently taken on the task of sending out customer statements. I find that the User Definable Form has a great layout that I would like to send to our customers. However, our company name and address does not print on the form even though the option is marked when selecting the statement. Any suggestions on how to get the company information to print on the SOP Statement - User Definable Form? Thank you, Kristy If you're talking about the statements printed using Tools>Routines>Sales>Statements, then you'll need to modify t...

Define a name in VBA
Hi All, I need a VBA code to select a non-active sheet(TEST) and then detect non-blank area to define a name(GI) to it. Thanks in advance Bijan HI. Try : Sub test() Dim LCol As Integer, RCol As Integer, TRow As Long, BRow As Long Sheets("TEST").Select LCol = Cells.Find("*").Column RCol = Cells.Find("*", [IV1], , , xlByColumns, xlPrevious).Column TRow = Cells.Find("*").Row BRow = Cells.Find("*", [A65000], , , xlByRows, xlPrevious).Row ActiveWorkbook.Names.Add "GI", _ RefersTo:=ActiveSheet.Range(Cells(TRow, LCol), Cells(BRow, RC...

Printing Statements
User is mass printing customer statements and has to print them individually. Has anyone experienced this problem that can help with a solution. Thanks! ...

Synchronizing between 2 offices some thoughts please
Hi Guys, I am looking for ideas on keeping a database synchronized between 2 offices, London & Manchester. I know the easiest way would be to create a web based database which we would both log into and process from that point, but I assume we would loose the efficiency of the local reporting and other aspects of a local copy of our data. The other thought would be for us to pass data between the offices on a frequency and maybe run an update query to sync the data. The database is a contacts database so it is mainly updating call notes made during the course of the day. Any thou...

How to prevent add ins being included in distribution worksheet?
The personal workbooks that I use on my machine use several home grown add ins, some of which link to other workbooks on my machine. However, the business workbooks that I produce and distribute to my clients don't need those addins or the links. How can I prevent my personal addins from becoming part of my business workbooks so that my clients don't get warnings about links not being updated? Convert the formula with links to values is one way. If I have a UDF (say) that is useful to others, I won't put it in my personal.xl* workbook. That's for stuff that only I use. ...

Self Referencing If Statements, Iterations
Previously, I created several self referencing If Statements that would return data when a toggle cell was equal to what I was looking for and would not change if the toggle was equal to something else. This had the effect of providing a data table without having to have the input functions on the same tab as the table. For example, on an excel merger model, on a cases tab I had many different "cases" (one company acquired another at a 10% premium, 15% premium, 20%, 25%, 30%, etc.). On another tab in cell A15, I had this if statement =if(CASES!$A $1=A$14,RESULT,A15) then I would have...

Statement Date
I enter my transactions manually for some of my accounts, ie utility bills. These transactions always have different payment dates, statement closing dates, service dates, etc.. Is there any way to enter the statement date on money 2007 deluze version 16.0.120.1303? I would like to do this so that I know what month I have just paid. In microsoft.public.money, OfficeNDN wrote: >I enter my transactions manually for some of my accounts, ie utility bills. > >These transactions always have different payment dates, statement closing >dates, service dates, etc.. > >Is there...

Nested Conditional Statements
Hello - I have a column within a report that has several versions of a particular entry. So I wrote a series of queries that would help to identify the different versions, see below: Version 0: IIf(InStr(Report![Column],"Business")>0,"Version 0","") Version 1: IIf(InStr(Report![Column],".1")>0,"Version 1","") Version 2: IIf(InStr([Report]![Column],".2")>0,"Version 2","") Version 3: IIf(InStr(Report![Column],".3")>0,"Version 3","") Version 4: IIf(InStr(Re...

I thought is was supposed to learn
Every transaction I make with my debt card always has the same store at the payee "Moka House" and it is always lists as a "Insurnace" it is driving me crazy. Can anyone suggest what I can do to fix this to make the program learn? Donnie In microsoft.public.money, Donnie Peterson wrote: >Every transaction I make with my debt card always has the same store at the >payee "Moka House" and it is always lists as a "Insurnace" it is driving me >crazy. Can anyone suggest what I can do to fix this to make the program >learn? Go to Accounts&...

Crystal Report for Account Statements - accountReceivableHistory,
Rather than using the built-in account statements, I'd like to do it in Crystal so that I can have full control. I'm hoping that someone else has done this work and can perhaps provide a Crystal report. Thanks for reading. Tim ...

switch statement
is there a switch statement that i can use in a cell as a formula? i have a value in col a. in col e i want that if the value in a is 1, it should return the valu in col B, if it's 2, return col C if it's 3, return col D. I know that i can do this with a nested if statement but i prefe switch - if someone can please tell me how to do this i would really appreciat it. Thank you -- tkapla ----------------------------------------------------------------------- tkaplan's Profile: http://www.excelforum.com/member.php?action=getinfo&userid=2298 View this thread: http://www.exce...

Define view in a Task dashboard?
I've built a couple of Outlook digital dashboards in the past, but I'm having trouble with my latest in Outlook 2003. Hopefully someone here can help. Please forgive the cross-posting; I wasn't sure in which group I'd find the most people familiar with digital dashboards. In the past, the below code worked perfectly. <OBJECT ID="Tasks" height=500 width=437 classid=CLSID:0006F063-0000-0000-C000-000000000046> <PARAM NAME="Folder" VALUE="Tasks"> <PARAM NAME="View" VALUE="Simple List"> <PARAM NAME="Nam...

Define name box size too small for viewing large formulas
Hi, When we create a new name using insert and define name then if the formula is long it becomes difficult to view the whole formula. Also one is not able to use navigation buttons left,right here as if we do that then the formula gets modified. is there any way to see the whole formula. Like for creating ever expanding validation list using Debra's technique one uses offset etc but one is not able to view the whole big formula. Please guide me. Regards, Hari India Hi try hitting F2 while in this text box. After this you should be able to navigate within this box. -- Regards Frank ...

OFX statement download now need to SAVE instead of OPEN
The problem: Bank of America offers the option to download statements from their website. I used to be able to ask for the download and get the typical Internet Explorer dialog about whether to "OPEN" or "SAVE" the file. I would click "OPEN," the .OFX file would process, and Money would say "IMPORT COMPLETED." For the past several weeks, this has been broken. I can "OPEN" the file all I want, but Money does not process it. If I "SAVE" the file to my harddrive instead as a .OFX file, and then double-click on that file, Mo...

AR Statement in Crystal
I am currently working on producing the A/R statement in Crystal 9.0. We are running GP 8.0. Crystal doesn't seem to be able to pull in all the customers. I am using table RM00101 and pulling custnmbr and custname. The inactive field is set to no and adrscode to 'STATE'. When I run this query using smartlist from within GP, I get a count of 823 customers. When I run this in Crystal, I only get 251 customers returned. Any ideas? In Crystal, are you restricting on RM00101.dbo.INACTIVE with the value "No"? If so, that should be 0 (0 = Active, 1 = Inactive). Y...

IF Statement #25
I am attempting to use an IF formula to do the following: IF sales are less than $75 no commission IF sales are >=$76 but < $150 1% commission IF sales are>=$151 but <$300 2% commision IF sales are> $300 3% Commission The Commission paid is stepped at each point and any amount in betwee the breaks also must have the commission paid. Could some one please provide some pointers as to the right way t approach this. Thanks Danie -- Daniel Sloa ----------------------------------------------------------------------- Daniel Sloan's Profile: http://www.excelforum.com/member...

APAYs thought I thought were cancelled are still being sent
BIG PROBLEM- I had cancelled APAYS in Money 2003. No problem. Now I have upgraded to Money 2004 and these long dead APAYS are automatically being transmitted to my bank and I cannot prevent this from happening because they are not appearing on my sceduled bills calendar. I have no apparent way of preventing this so I have been resorting to cancelling payment after the transaction appears in my register! Call your bank and tell them that you tried to cancel but since it didn't work, you need to have them manually cancel the Apay. "Carlos" <carlostim@msn.com> wrote...

Modal dialog not always receiving user defined messages from PostMessage()
Hi everybody, I have a simple dialog based application that reads data from a serial port in a worker thread (MonitorSerialPort()). When the worker thread detects data, it uses PostMessage() to send a message to a custom class that I derived from CWnd (CSerialDataProcessor). CSerialDataProcessor takes the raw data from the serial port and parses it into application specific format. It then posts a message to a modal dialog and the modal dialog in response to this message updates a control to display the parsed data to the user. This scheme works for the most part, however, when I stress test...

Statement Line Items not purging off statement
I have a few customer statements that although payments and returns have been applied to invoices and paid in full are not purging off their statement?? There are a few different ways to achieve this outcome. This method is when NOT using National Accounts. I find most customers do not want to run the Paid Transaction Removal process too soon, in case of voids and credits are required. We modify the RM Statement and add a cacluated field to supress the body when the current transaction amount is zero. First step is to link the RM Open File to the RM_Statements_TRX_Temp, us...

If statement- formula
Well I'm stumped again. If close!ag2:ag19999 contains "xyz" enter contents of close!ag2:ag19999, otherwise enter contents of close!ae2:ae19999 thanx, ~Julz Hi what do you mean with 'enter contents'?. Do you want to add them? If yes try =SUMIF(close!ag2:ag19999,"xyz",close!ag2:ag19999)+SUMIF(close!ag2:ag199 99,"<>xyz",close!ae2:ae19999) -- Regards Frank Kabel Frankfurt, Germany Julz wrote: > Well I'm stumped again. > > If close!ag2:ag19999 contains "xyz" enter contents of > close!ag2:ag19999, otherwise enter cont...