Googles appar
Huvudmeny

Post a Comment On: cbloom rants

"06-17-11 - C casting is the devil"

12 Comments -

1 – 12 of 12
Blogger jfb said...

Hmm.

Maybe something along the lines of casting to unsigned T first, then instead of A < min, A - min > A. That'll shut any warnings right up.

Be sure to cast A and min to unsigned before doing that, however. Othrewise, whole program optimization on some compilers (Clang, for one) may take that as an opportunity to optimize that to 'false' if it can prove min >= 0 and eliminate it (signed integer overflow behavior is "undefined", so...).

June 17, 2011 at 6:48 PM

Blogger ejulien said...

Sorry, I did not read the whole post but how about using an union?

union MultiPtr
{
char *pc;
short *ps;
};

mptr.ps[0] = 16;
mptr.pc++;
mptr.pc[0] = 8;

June 19, 2011 at 6:59 AM

Blogger won3d said...

"Maybe it would be nicer if I left off the type it was casting from in the name."

The real problem is that you're not getting away from implicit casting on the argument. If you use the incorrect version, you can get screwed.

Also, ryg and others suggest that "From" names seem to be better than "To" names:

U8 byte = U8FromS32(some_int)

June 24, 2011 at 3:08 PM

Blogger cbloom said...

"The real problem is that you're not getting away from implicit casting on the argument. If you use the incorrect version, you can get screwed."

How's that? If it implicit casts without a warning then you should be fine (?)


On further thought I'm pretty sure that the overloaded version that leaves off the from is The Win , eg .:

U8 byte = clampU8(some_int);
S16 word = checkS16(some_long);

June 24, 2011 at 4:27 PM

Blogger won3d said...

I wasn't being clear because I was talking about two different things. But yeah, it is definitely better to templatize the argument, and probably not the return value. Without that you could have the problem:

U8 byte = U16toU8(some_int)

Where the int to U16 conversion screws you before your clamping happens.

The other thing I was talking about is just what you call it. Like clampU8() is a weird name since it sounds like you're clamping a U8, not TO a U8. You're probably thinking about it in terms of where the template type would go. So something like:

U8 byte = U8Clamp(some_int);

Looks better to me.

June 24, 2011 at 6:11 PM

Blogger cbloom said...

"U8 byte = U16toU8(some_int)
Where the int to U16 conversion screws you before your clamping happens."

Yeah, but no C compiler should silently do that implicit cast ? You should get a compile warning there.

June 24, 2011 at 6:26 PM

Blogger won3d said...

I tried it with gcc 4.2 -Wall (old, I know) and clang through the web demo compiler (which is using default warnings level) and got no warning, even with optimizations. They both complain if I try to pass in a too-large constant. Maybe you should try?

char foo(short s) {
return (char)s;
}

int main() {
int i = 100000;
return foo(i);
}

June 24, 2011 at 6:40 PM

Blogger cbloom said...

main.cpp(236) : warning C4244: 'argument' : conversion from 'int' to 'short', possible loss of data

June 24, 2011 at 6:50 PM

Blogger won3d said...

What warning level is that?

Maybe my compilers will start warning narrowing conversions one day. But I guess if you're going cross-platform, you probably shouldn't depend on it.

June 24, 2011 at 7:02 PM

Anonymous Anonymous said...

SafeInt solves out-of-range errors on casting.

July 8, 2011 at 9:25 AM

Blogger cbloom said...

I'm not a tiny code fetishist, but holy bejeezus SafeInt might be the most over-engineered over-sized thing I've ever seen.

July 8, 2011 at 10:45 AM

Blogger castano said...

and it's "used extensively throughout Microsoft" LOL!

July 13, 2011 at 9:58 AM

You can use some HTML tags, such as <b>, <i>, <a>

This blog does not allow anonymous comments.

Comment moderation has been enabled. All comments must be approved by the blog author.

You will be asked to sign in after submitting your comment.