- 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
I'm not sure which is worse: the line of code or that the comment includes an emoticon...
Admin
On C compilers for those CPUs, memcpy may be an intrinsic function that the compiler can generate code for inline when applicable (when size is "small"). If so, then you're home free.
When memcpy isn't a compiler instrinsic, then quite likely the mere function setup+call+return may eat up more cycles than the actual copying of the memory in question. Never mind the time spent inside of memcpy. I know that's the case on Z8 Encore!, using ZDS II 4.10.x C compiler, large model, static frames.
Cheers, Kuba
Admin
This can blow up on signaling NaNs, depending on the current process-specific "what should I do on signaling NaNs?" behavior.
Which can be changed by any .dll you load into your process.
http://blogs.msdn.com/oldnewthing/archive/2008/07/03/8682463.aspx
Admin
Obviously, the real wtf is that he used unsigned int instead of uint32_t. How can you guarantee that unsigned int is 32-bit?
Admin
this just goes to show that when you look at your own code from 4 months ago, it may have been written by someone else. Good reason for decent comments.
Admin
Admin
with any luck, someone will change the hardware hell runs on and that the array that circle was forced into will overflow into a nicer area...
Admin
Admin
Here is my own story along the same lines: http://www.dfan.org/writing/comment.html
Admin
Admin
I admit I was being a bit pedantic with my "floating point formats differ" comment, as the only platform I've ever used that doesn't support IEEE floating point is the Vax - and I don't think I'll be programming for one of those again. I also had a feeling that if you knew enough to use unions properly, then you'd also ensure network byte order elsewhere in your code. My comments were more of a heads up in case anyone used your example but then wondered why their x86 machine couldn't transmit floats to a SPARC or PowerPC machine. Personally, I'd still use XDR, but then I've got a wrapper library that makes it easy.
Admin
What if that line of code was in the initial import that rjacobs did? The only wrongdoing we would be guilty of then, would be importing it...
Admin
That really isn't a WTF. That's a reasonable way to do that. You're changing the type for the benefit of the compiler. There's nothing wrong with doing that. A beginner or mid-level C programmer might not see what it's doing, but it is the correct way to tell the compiler "treat these four bytes as ..." Everything is bytes anyway. Types exist only for the compiler and the programmer.
The thing to do is to have a simple comment that says, "this treats these bytes of float as an array of char", and that's it.
JBoss Seam training
Admin
This, of course, makes the assumption that the sending and receiving machines have same byte order (htonl(3) and ntohl(3) help with that), and also that the machines have same sort of floating point representation, which might actually be a safer guess since I suppose most machines have IEEE floating point numbers... But if they haven't, I suppose you could implement a function that converts between different FP representations.
Admin
Admin
Actually the code is pretty good at converting a float-y type into an int-y type, which may be necessary if you need to bit-twiddle a float. Perhaps I'm only posting this because I've written something similar. ;)
Admin
Admin
Any code you've written more than six months ago may as well have been written by someone else.
Admin
In the future, all coders will be required to think THREE times.
And if that doesn't work, we'll send you to a mandatory training class.
Admin
Admin
float x = 1; char * v = (char *) x; v[0]..v[8]
Admin
The only legal (ie. not undefined behavior) way to do this is to cause N = sizeof(float) char or unsigned char objects to alias a pre-existing float object.
What this means in practice:
While the union "cast" works in practically all compilers, it's still undefined behavior according to the standard, and so are all the other "clever" ways of causing aliasing. For further information, refer to ISO/IEC 9899:1990 and http://www.cellperformance.com/mike_acton/2006/06/understanding_strict_aliasing.html
Admin
or v[0]..v[3], depending on architecture.
Admin
or v[0]..v[3], depending on architecture.
Admin
I loved it!
Since this is true confessions...
Anytime I take a look-see at my code, I find at least 1 WTF-y line in it. I'll even comment 'This looks WTF and is done because...'
I envy those who have the time/resources/ability/scope/authority/etc to plan each line of code to perfection.
Admin
Fixed.
(Actually, so does John's, but he's already been corrected ;)
Admin
This sort of thing happens to me everytime I come back from vacation. "WTH wrote this crap!?". Well - I did.
Admin
Better way? Store it as a float and memcpy the chars into right place. That'll get you around alignment stuff and other unpredictable behaviour. Plus it doesn't look half as bad as that.
Admin
Wow, just wow! Makes me remember what I dislike about C...
Admin
Admin
This is actually a very good example to show C programming students with the question: "How can this work most of the time ?"
Admin
Of course, where I'm at right now they switched from one source control repository to another after primary development was complete, so most witch hunts end there...
Admin
D'oh! So nearly...
Unfortunately, &a needs to be amended to a I think :)
Other than that I agree this is the tidiest way in general, though given the context of the original post, I'd be tempted to use:
Admin
Hey! I recognise that line of code! Shame I didn't think twice before I wrote it - maybe even thinking once would have been better?
Admin
I tried to follow this, but I don't quite get it. Anrs solution seems to work great, it's Maks' that shits the bed. Offset of 4 aside, the first parameter to memcpy in the store function case is going to be a pointer to the address of the destination, not the the address of the destination itself. Shouldn't this read:
memcpy(a + 4, &f, sizeof(float));
Pointer type in the first and second parameters.
Anrs' worked fine though, as &x[4] is already a pointer type. Is there something wrong with Arns' code that I'm missing, or was it the conversion of Arns' memcpy call to a function that screwed it up?
Admin
Its easy to accidently check in stuff under a different name. If you have a name that does builds or a checkout script that uses a name and password, svn remembers the last action credentials. So if you use tortoise or something to commit, it commits the code under that name, which may not be your name.
Admin
Admin
That's when you get around to the "optimization" phase of a project. As far as anything is concerned, a proper functioning memcpy() will work regardless of the original types, alignment (source, destination, or host architecture), or other issue (even handling overlapping memory regions).
A programmer should use memcpy() rather than their own copy routines. If the memcpy() is implemented inside a performance critical area, then perhaps it's something that can be optimized later.
But if the code doing the packing/unpacking is only used to ship data off a wire, that's not performance critical, the convenience of knowing that memcpy will "get it right" versus the overhead of doing it yourself (especially months later when some bug or fix has to be applied that changes an underlying data structure) mantenance...
Plus, you avoid code that looks like the article. Would you rather see a memcpy() or the article code when tasked with finding a bug?
Admin
Aliasing violation. These days your compiler should have a good 'ol whine about that.
Admin
Could be worse.
The following is lifted from the Quake3 source code, trimmed and altered for brevity:
Where COM_Parse takes a char** that will slide over the text as it is parsed into tokens and returns a char* to an internal buffer containing the current token. If no more tokens are available it returns said buffer filled with only a null terminator.
Subtle, but quite destructive.
Admin
Admin
We would like to warn our readers that posting misleading and incorrect advice on TDWTF in a way that demonstrates very clearly that you do not understand compiler technology is NOT A GOOD WAY TO ADVERTISE YOUR TRAINING COURSE.
Here's a google term for you: "Type-based alias analysis". It's not just a theoretical argument. Ignore it, and your code WILL be invalid.
Oh, p.s.: Exactly how does casting something to (unsigned int *) and then dereferencing it turn it into "an array of char"?
Admin
That's a deliberate WTF joke about the undefined behavior present in writing into an int field of a union and then reading from a float field? Fair enough, if so: this is one of the most common bugs/misunderstandings among intermediate C and C++ programmers. Type punning is allowed in only very limited cases, and int/float isn't one of those cases.
Admin
I'd say, if speed is your primary concern, you're likely to run into more of these situations. for example: float a, b; if (((int)&a) > ((int)&b))
Admin
Ain't nothing unusual with developers writing stuff like that when they're new to commercial software development. Most developers starting out do that (complete with smileys in the comments) because they think it'll impress. As they get older they figure out the bigger picture and stop doing it (as Rob did here).
The next level of experience might say that the WTF here is how come a less experience developer was able to get code like that into the code-base without it being picked up in a peer review?
Then you learn that because project tasks like design, CM, code review and testing don't actually provide marketing with new features, they're seen as obstructions to getting a product out on time so 'they will get done later...'
Admin
Admin
Ah, the tangled old code we [try to] forget...
Admin
It was the code fairy - taking good code and leaving a dollar... and bad code.
Admin
I love reading WTF for exactly this kind of thing. I have done the same exact thing. Internally accusing someone of some infraction only to review the logs and find it was me. You made my morning.
Hans
Admin
Is anyone not going to comment on the difference between: memcpy(x, &value, sizeof(value)); and *(unsigned int *)&x[4] = ...
The first stores the value in x[0], x[1], x[2] and x[3]; The second stores the value in x[4], x[5], x[6] and x[7].