- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Their use is discouraged, but not officially deprecated. And their use is unsafe due to a lot more than types too. (Look in the next paragraph at the definition of MAX; thanks to the wonderful world of macros, all those parens are necessary. And it's still not the same as an inline function.)
I would advocate that macros should almost never be used in either C++ or C99 code to create constants (#define PI 3.14) or functions (#define MAX(a,b) ((a)>(b)?(a):(b))), especially the latter.
However, macros have other uses where you're not just making an inline function or constant, but using macros almost as new language features where there is no replacement. Here I feel that macros are quite respectable.
Not legally. "Unconsting" physically const objects (those declared as const double PI = 3.14 for example) produces undefined behavior.
(Well, okay, this isn't exactly true. But if you declare PI as above then do ((int)&PI) = 5, that IS undefined. You have to change a physically const value. And mutable members complicate matters too.)
How do you get that?!
Admin
For future reference, say those lines are the body of IntersectP()
What's the return type of IntersectP?
If you have a #define BOOL int (or typedef BOOL int), now someone sees 'BOOL IntersectP()' and won't even think to check for MAYBE. That's no good.
You can say 'int IntersectP()', but now the return doesn't really tell you what you need, and it doesn't tell the compiler what it needs, and it doesn't tell Lint what it needs. (Incidentally, these are problems with the previous solution too.)
Best is 'tristate IntersectP()'. It tells the programmer about all three options, it tells the compiler about all three options, it tells source analysis programs about all three options.
Even ignoring precedent, I think the last solution is easily worth the extra namespace pollution.
Admin
Can't believe 4 pages of comments and nobody has added
#define ASK_AGAIN_LATER 999
Admin
I never said using #define was ideal, but I'm simply trying to get across that I can imagine a situation, especially given the example domain where this would be a problem.
Imagine the library described where TRUE and FALSE are already defined and used (with the possibility of typedef BOOL int).
The problem with enums is that if you have a library that doesn't know about them you can't use them correctly (they don't upcast). You can use #defines without incident.
So let's say in the external library TRUE and MAYBE do the same thing.
From the external library:
typedef int BOOL;
#define TRUE 1 #define FALSE 0
void g(void) { }
BOOL f(BOOL a, float c, float d) { if (a) g(); return (TRUE); }
From your library:
enum mytype { MYFALSE = FALSE, MYTRUE = TRUE, MAYBE = 2 };
mytype h(void) { return f(MAYBE, 0.2f, 0.4f); }
Now this returns a compile time error because f() returns an int and you're returning something else. Now you're doing this all over the place:
return (mytype) f(MAYBE, 0.2f, 0.4f);
which is to say redundant. What you really wanted was something that could participate in a base/derived relationship, but these are enums and that's not how it works.
I'm not saying this is ideal (for the forth or fifth time), but what I am saying is that perhaps the author was trying to avoid a lot of headaches and code writing.
There's also the added pitfall that somewhere in the external library they have a call like
if (a == TRUE)
and then well you're screwed. Perhaps they tried it the #define MAYBE 2 way and it worked and they never went back. I've certainly got hacks in my code that could use a little love, but then maintainence programmers usually will tell you that if it works -- no touchy. Again all I'm asking for it for people to at least acknowledge that there are circumstances where a compitent, reasonable programmer might find himself or herself writing #define MAYBE 2.
Admin
I can't speak to the situation here as to how good of an idea it is. I would say that #define MAYBE 2 could be the least bad solution of a few, and that it also could be a "temporary", proof-of-concept hack made permanent.
My earlier post was mostly doing two things; first, presenting another reason to use enum that I hadn't yet seen (though it's quite possible I missed), and saying that the increased type safety alone outweighs the namespace pollution issue IMO.
Admin
It's simple. They are testing for true, false, and Schrodinger's Cat.
Admin
the greatest greatness of this piece of code is that if you ask:
you get a TRUE answer, which is in fact, correct. And at the same time if you ask:
you also get TRUE and that is correct too! brilliant.
Admin
[quote user="EvanED"][quote user="merreborn's nemesis"]
Then how do you get true and false in C code if you can't use C99? Or are you going to say that using C89 is always stupid?
[/quote]
#define TRUE (0==0) #define FALSE (!TRUE)
Admin
Doesn't the Java compiler complain about unreachable code?
Admin
At first i thought the code is written by a female (men think true|false, black|white, buddy|sexmate , even if they don't admit it )
But then i realized it couldn't have been ! For women would write it like this
#ifdef FALSE #define TRUE = FALSE #endif
#ifdef TRUE #define FALSE = TRUE #endif
#ifdef FALSE && MEN #define MAYBE = FALSE #end
#ifdef TRUE && MEN #define MAYBE = FALSE #end
#ifdef FALSE && LOGIC #define MAYBE = TRUE #end
Enjoy life as it is, we're all gonna die :D
Admin
What a hero...
BTW: I hate programmers which write code like this:
etc.
But that's my personal view...
is the ony and ONLY correct way to use booleans ;-)))
Also there is no fuzzy logic in this MAYBE anti-pattern...
It's simple stupid...
;-))))
Admin
Very amusing. I remember working on some Merant code once that introduced a "Tri State Boolean" class. TRUE, FALSE, and 'CANT_TELL_YET'. Classy.
Admin
Please, please... this is a WTF ! multi-value logic does'nt exists, it is fuzzy-logic. In fuzzy logic, MAYBE isn't 2, it is much more precise ! In fuzzy-logic (used in A.I., in washing machines or your elevator system), 0 is FALSE for sure, 1 is TRUE for sure, and all real values between 0 and 1 are probabilities. 0.95 is TRUE with a 95% probability, and is considered as TRUE with 5% error margin. The WTF is to assign 2 for "MAYBE", knowing there is an infinite count of "MAYBE" between TRUE and FALSE.
According to fuzzy-logic, FILE_NOT_FOUND is -1 and BRILLIANT is 1.1. Or maybe not...
Admin
You should see HTML5's