Comment On It's not how big it is ...

... it's the context in which you use it. And depending on how you use this C constant that Henrik A stumbled across, it can get pretty interesting ... [expand full text]
« PrevPage 1Next »

re: It's not how big it is ...

2004-10-21 14:40 • by 52T

How does code like this even get past "does it run?" testing?

re: It's not how big it is ...

2004-10-21 14:54 • by Dave Mays
Smells like deliberate obfuscation.

re: It's not how big it is ...

2004-10-21 14:57 • by Smells Like ...
C

re: It's not how big it is ...

2004-10-21 15:14 • by Mr. Operator
Seems like somebody forgot the difference between ^ and pow()

re: It's not how big it is ...

2004-10-21 15:26 • by Ryan Farley
"It's not how big it is...it's the context in which you use it"

Can I get that on a T-Shirt? Hehe.

re: It's not how big it is ...

2004-10-21 15:40 • by black
WTF?!?!?

re: It's not how big it is ...

2004-10-21 15:41 • by Hexy
This is definitely one of the bigger WTFs I've seen in a while. It's fairly obvious they're trying to use the built-in x^y operator (which doesn't exist in C/C++). But this example also demonstrates why you should enclose most macros in parentheses because of unexpected operator precedence. But if you're using C++, you might as well just use a constant:

const int v = pow(2, sizeof(SpaceId)) - 1;

re: It's not how big it is ...

2004-10-21 15:44 • by Ian Bicking
((1 << sizeof(SpaceID))-1) would also work.

re: It's not how big it is ...

2004-10-21 16:24 • by Guayo
nice one...
I think it's a double WTF because as someone already said it, it seems that they are confusing pow() with ^.
And also it's a WTF for not considering of operator precedence.

re: It's not how big it is ...

2004-10-21 16:50 • by WanFactory
My operator precedence is a little rusty, but here's a stab at these crazy evalutions based on 2^4-1

(2^4-1) becomes (2^3) becomes 1
2^4-1==1 becomes 2^3==1 becomes 2^0 becomes 2
1==2^4-1 becomes 0^3 becomes 3
1+2^4-1 becomes 3^3 becomes 0
2^4-1+1 becomes 2^4 becomes 6
2^4-1*5 becomes 2^-1 becomes -3

this is just made my day

re: It's not how big it is ...

2004-10-21 17:40 • by josh
Well... technically x^y does exist, it's just not exponentation.

((1 << sizeof(SpaceID)) - 1) will work, but it's not right. First, (1 << sizeof(SpaceID)) will overflow. The compiler will probably give you 0 instead, but that's undefined behavior so it doesn't have to. Then the whole thing is -1, which is actually kinda small for an int.

If you made that 1 unsigned (1u), then you're guaranteed to get zero (assuming sizeof(SpaceID) == sizeof(unsigned)), but subtracting 1 gives you UINT_MAX, which won't fit in an int. Usually the compiler would give you -1 here as well, but that's also undefined behavior.

If SpaceID really is a typedef to int, you should just use INT_MAX. (or -1, if that's truely what you want. but then I suspect typedef unsigned SpaceID; and UINT_MAX is better.)

pow would also work, but it's not a compile-time constant because of the function call (even if you're compiler's clever enough to do it at compile time), so there are places where you can't use it. And if you're compiler is less clever, it's not a good habit to do things at run time that can be done at compile time.

re: It's not how big it is ...

2004-10-21 19:26 • by Dare
Josh: Why would (1 << sizeof(SpaceID)) overflow? If SpaceID is defined to be an int, then sizeof(SpaceID) is 4.

re: It's not how big it is ...

2004-10-21 19:34 • by J.p.
It wouldn't overflow, but it also wouldn't give the right answer. Bit shifting is multiplication by two, not exponentiation. Shift 4 to the right, you'll get 8. 8-1 = 7. Right?

re: It's not how big it is ...

2004-10-21 23:05 • by 5pvps
J.p.: No, shifting 4 to the right would get you 16. Each place shifted over is a multipication by two. Since the base in this exponentiation is 2, then there's no difference -- multiplying by two n times, or putting the base to the power of n.

1 << 4 == 1 * ( 2 * 2 * 2 * 2 ) == 1 * pow ( 2, 4) == 16.

re: It's not how big it is ...

2004-10-22 03:20 • by xyz
ROTFL... *assuming* he wanted to do pow() exponentiation, and do it right, anyone got that MAX_PID = 15 ?

If PID is ProcessID (otherwise this is another WTF), it isn't a very small number for a maximum ?

re: It's not how big it is ...

2004-10-22 03:48 • by Voblia
Bwahahah it's 3 in one - the guy is trying to get a max int yet he doesn't know he is geting size in bytes not bits!

re: It's not how big it is ...

2004-10-22 05:20 • by necroyeti
ahhh, thx, that's a real WTF, and definitely one of the best ever :) Now I just like to know at how many places in the code this BS was used.

re: It's not how big it is ...

2004-10-22 05:28 • by somormujo
Good catch Voblia,

even better to think about having something like:

#define MAX_PID 2^sizeof(SpaceId)^8-1 //SpaceId is typedef int, sizeof(int) is 4

Hahahaha

re: It's not how big it is ...

2004-10-22 05:30 • by Lothar
Voblia: The author of the code knew the effect of sizeOf, otherwise the comment
> //SpaceId is typedef int, sizeof(int) is 4
wouldn't make sense.

re: It's not how big it is ...

2004-10-22 05:35 • by Warp
A WTF in these comments: People are writing the "shift to left" operator<<, but saying "shift to the right".

(Shifting to the right by 4 (ie. value>>4) *divides* the value by 16.)

Can't coders distinguish left from right?-P

re: It's not how big it is ...

2004-10-22 08:20 • by JD
I figured the comment was put in not by the original coder, but by the submitter so we wouldn't all be going "well WTF is SpaceID anyway?!?!??!?!?!".
A clarification, Alex?

re: It's not how big it is ...

2004-10-22 08:30 • by Henrik A
JD - That's correct, I put that comment there.

I'm glad you guys like it! This has probably got to be the single worst line of C I've ever seen. :)

re: It's not how big it is ...

2004-10-22 08:34 • by Lothar
Henrik A: You're right, the WTF per line ratio is optimal here.

re: It's not how big it is ...

2004-10-22 10:59 • by Evan M
Alright, in this guy's defence, if the ^ operator actually did powers, and instead, we replace it with the pow() function, then the order of operations is fine.

However, the use of sizeof() is wrong twice. First, you have the byte vs. bit idea. But the other failure that we have here is the fact that he doesn't consider negative numbers at all. The max value of an int is pow(2, (32 -1)) - 1. Now that's a major wtf error.

re: It's not how big it is ...

2004-10-22 11:02 • by Ghetto Pimp
cocky sumbitch, that Evan

re: It's not how big it is ...

2004-10-22 11:22 • by fluffy
And anyway, pow() returns double, which is stupid and inefficient and can also lead to roundoff errors (granted, not in this situation, but still). Just use 1<<x instead.

OT

2004-10-22 12:28 • by Mike R.
# re: It's not how big it is ... 10/22/2004 5:35 AM Warp

... Are you the same Warp as in the POV forums?

re: It's not how big it is ...

2004-10-22 20:11 • by Oliver Klozoff
This same problem occurred on a in-house system:

Our company, before I was hired, needed to find a way to generate something like a four-digit "hash" from another number.

Rather than take a secure hash algorithm, like SHA or MD5 (or hell, even MD4 or MD2) and work from there, they rolled their
own, involving crazy things like
floating point multiplication and sprintf. And since all they knew was VB, they wrote the sample algorithm in VB.

At the very end, the algorithm would run an extra loop if the following test failed:

hashValue < 10^(hashDigits - 2)

In case it's not immediately obvious, this basically checks if hashValue is less than 100 -- if it is, it runs again. The idea was to make sure the hashValue had at most one zero at the beginning.


Fast forward: This algorithm was then sent to a developer writing a program for a small hardware device (about the same size as a credit card terminal). This developer knows C (the language most often used for the CPUs of those devices), but not Visual Basic. Fortunately, as some of you may know, VB is very easy to understand by a programmer who knows another language. And for the stuff that he didn't get, he could ask us.

Has anybody guessed where this is going yet?

The last line -- the one attempting to see if there were too many digits -- was copied exactly... Changing the meaning from 'hashValue < 100' to 'hashValue < 8'.

For an added bonus, the hardware device has no floating-point unit -- the floating point math is 64-bit software emulated. Which means that, due to rounding, the 80-bit FPUs in our x86 desktops sometimes generated different hashValues than the hardware device did.

To top it all off: When I actually went back and analyzed the algorithm -- about 30 lines of code -- I discovered that it reduces to 1 line of C, involving four 64-bit integer multiplies.

How's that for WTF?

re: It's not how big it is ...

2004-10-22 22:15 • by foxyshadis
Psst, fluffy, read the comments before you post.

It seems this is all way way too much work. Just #define this as INT_MAX, UINT_MAX, or whatever number you need, _on the line after the typedef_. That way you don't have to play games to get the value (and still get it wrong), and always remember to change it. Given the utter disregard the C spec has for type standards of any kind, this seems to be the only safe way to do it. (Short of defining everything as a long long and assuming there's a snowball's chance in hell of generating a value over 18 quintillion in 32-bit operations. If that's still a problem, there are 256-bit integer math libraries out there. *laughs*)

re: It's not how big it is ...

2004-10-28 04:05 • by Hartmut
I don't do any programming in C, but given the discussion above and the example that Oliver gave, wouldn't the expression "hashValue < 10^(hashDigits - 2)" end up meaning "(hashValue < 10)^(hashDigits - 2)" in C? The two possible outcomes are 0^2, which comes out to 2, or 1^2, which comes out to 3. In both cases, the end result is non-zero, which means the test would be logically equivalent to "if (1)".

re: It's not how big it is ...

2004-10-28 20:07 • by peter beaguely
id base my site/job security on techniques like this. fucking awesome.

re: It's not how big it is ...

2004-11-04 13:12 • by Pendant
You _shouldn't_ enclose macros in parenthesis. If you don't, then they'll never work as expected and people will actually read them before using them. And reading a macro before using it is what everyone should do.

Plus, you'll end up with people on your team who code (in C++) things like

if FAILED(hr == pInterface->DoSomething())
{
}

and think they're just fine. After all, it compiles.
« PrevPage 1Next »

Add Comment