- 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
No, I cannot spot the bug, no matter how much I Zoom into the code. Nice normaliZation macro, cannot think of a way to optimiZe it anymore. As a matter of fact, I realiZe right now, that I need such an amaZing macro myself.
Admin
Z is uppercase, so missing lowercase z
Admin
It doesn't handle lower-case 'z'. It maps upcase Z to Z.
Another bug is that it evaluates X multiple times. It could produce astonishing results if you try TO_UPPER(getchar()).
gene
Admin
The macro also evaluates (x) 26 times. So if you did something like this:
TO_UPPER (*(p++))
It would increment p 26 times.
Admin
Mark Twain probably would have responded along the lines of:
And zen vinaly ze drem has com tru!
Fabian (who probably should not have suggested knowing what Twain might have said...)
Admin
I wonder why someone would do case conversion like this. Is it an attempt to be so portable that your code works in the face of ASCII, EBCDIC, or whatever else? But then why not use C's toupper macro?
gene
Admin
I wonder why someone would do case conversion like this. Is it an attempt to be so portable that your code works in the face of ASCII, EBCDIC, or whatever else? But then why not use C's toupper macro?
gene
Admin
There is one other WTF.. This thing is not a normal function, but a macro! For the non-C programmers: a macro in your code is replaced with it's contents (like an inline function). So everywhere you write TO_UPPER("b"), that code will be replaced with the contents of that macro. In my example, x will be replaced with "b".
Admin
Wow, Who'da thunk this code could have been replaced by:
char ucase_tbl[256] = { .. insert appropriate characters here .. };
char chrupr(char c)
{
return ucase_tbl[c];
}
mmph. Actually, the casing table should probably be filled at runtime based on locale. And NO! I don't expect this to work with unicode.
Admin
Of course, subtracting 32 from the lowercase letter (within appropriate bounds) is far too great of a task to accomplish.
Admin
Ignoring all the other stupid things about this, wouldn't a switch statement fit a little better?
Admin
No zed for you!
Admin
Marco....[^o)]
Admin
The other classic WTF that you see happen in this sort of situation is a confusion of 'l' and '1'. If performance is that big of a concern, wouldn't you want to sort the characters based on frequency? Of course, when you care that much, don't you move to asm?
Admin
Polo...?
Admin
Yes! I knew someone would answer. [:D]
Admin
How about the WTF of doing it twice, just to be sure...
TO_UPPER(TO_UPPER('z'))
still didnt work? maybe try 3 times!
Admin
Aktshully, ASCII was defined so you can do
Pretty cool, uh
Admin
The above doesn't work for characters greater than 127.
Admin
Ooops, more specifically it doesn't work for anything not known to be either an upper or lower case character. { becomes [.
Admin
Both of you with your evil magic numbers. :@
Admin
Capital, not lower-case, 'Z' in the test
Admin
The macro also evaluates (x) 26 times. So if you did something like this:
TO_UPPER (*(p++))
It would increment p 26 times.
Admin
Nor does it work half the time with if the platform defines a 'char' as a signed value.
Admin
This is typical of macros, which is one reason why they are usually in upper case.
This is a more usual implementation of TO_UPPER:
Admin
Indeed! And if p[i] != 'a' + i (i = 0 to 24) and p[25] != 'Z', then p would be incremented 27 times.
Admin
Too bad...if only there the letters of the alphabet were somehow mapped to numbers. Then if the lower case and upper case letters were in the same order, they'd have a linear relationship, and you could just do some math to move from one to another after testing if they were in the lower case range or not....
Oh well, maybe someday computers will use some sort of numeric scheme behind the scenes to store characters.
Admin
Classic case of RTFM?
Admin
PONO
"What's in your wallet?";)
Admin
It's much better just to call a library function so you can do all different kinds of encodings.
Admin
I heard that programmer works for AOL. His (or her) routine is used on some of AOL's mail server and causes ALL MESSAGES FROM AOL ADDRESSES TO BE IN ALL CAPS EXCEPT 4 TEH OCASIONLA LOWERCAES z LOL
Ahem.
Admin
But, as I understand what the original macro 'code' is trying to do, the ASCII value of the letters A through Z is lower than 127.
-dZ.
Admin
Irony:
2) The author is so "careful" to wrap 'x' in parentheses in case it is an expression, but no consideration is given to the effect of that expression being evaluated multiple times.
~ zahlman, er, I mean zahlman... dammit... Zahlman... there we go. ;)
(PS I just tried to sign up here, but my login seems not to work? o_O)
Admin
Actually I can think of one case where a macro like this would actually be more efficient than the more usual table based implementation: a constant argument.
The above macro called on to_upper('y') would be completely constant-folded at compile-time into just a constant 'Y'.
The normal table based implementation would normally not be eligible for constant folding.
So for those cases where you have to_upper() calls in the midst of your critical inner loops (you know, for that super-duper unbreakable encryption scheme you cooked up)...
Admin
I don't really know mutch about C, but wouldn't this function only work on strings of length one? Forcing you to break apart the word before evaluating each character separately?
So TO_UPPER("Account") would still be "Account"
Admin
Indeed, you probably should not have suggested it, because it was George Bernard Shaw who proposed the simplified spelling system to which you are alluding.
Admin
True, and TO_UPPER("account") would still be "account" because "account" is not a letter from a-z...
Doh!
Drak
Admin
"I don't really know mutch about C", indeed.
That macro is targetted at single characters. To convert a whole string you would have to loop it. Remember that C is often based on primitives where this doesn't reduce practicality. Higher-level libraries and hand hacking are often required for more convenient routines. On the other hand, super-high-level routines like *printf and *scanf are targetted at being maximally practical yet still standard (besides Microserf and GNU extensions for other types).
The problem with this code is that a perfectly servicable and much more sensible macro exists in ctype.h, and some environments provide a library function as well. This is one of those "should have looked elsewhere first" cases. How the developer did not pick up on the z/Z mistake is a real testament to carelessness.
Admin
This does not convert lowercase spaces to uppercase spaces. Wtf?
Admin
Which is bad because... it keeps every previous one 'open' while it evaluates the current one, making it less efficient than an if else if else if or a case switch?
Admin
if ((c>='a')&&(c<='z')) c -= 'a' - 'A';
It works for every character codification where alphabetic letters are consecutive (so no ASCII/EBCDIC problems).
Admin
I'm just waiting for Alex to say the uppercase Z was his typo!
Admin
WTF? Wouldn't the compiler treat them the same? I mean, its just a series of JNZ or such operations, just like a bunch of if/else/if/else or a case switch... no?
dZ.
Admin
WELL ISN'T IT NICE THAT SOMEONE IS GOOD ENOUGH CODER TO MAKE A CORRECT VERSION OF A WTF!!!1111oneoneone
Admin
Unless the caller gets lucky and the pointer just happens to be (char *) 'a' - then he'd get a mangled pointer.
Admin
What puzzles me is why Mark Twain ( from Missouri ) has a German accent?
Admin
WTF++
Admin
Wonder why zat damn function doezn't work?
Admin
In fairness, that would only work in ASCII
Admin
It also would be especially fun if the parameter was a function say
(((int)(rand() * 26)) + 'a')