tag:blogger.com,1999:blog-5246987755651065286.post3160347589004351002..comments2024-02-22T16:15:42.388-08:00Comments on cbloom rants: 06-17-11 - C casting is the devilcbloomhttp://www.blogger.com/profile/10714564834899413045noreply@blogger.comBlogger12125tag:blogger.com,1999:blog-5246987755651065286.post-72697629271932352202011-07-13T09:58:05.632-07:002011-07-13T09:58:05.632-07:00and it's "used extensively throughout Mic...and it's "used extensively throughout Microsoft" LOL!castanohttps://www.blogger.com/profile/08088335278984724562noreply@blogger.comtag:blogger.com,1999:blog-5246987755651065286.post-71239897737630348702011-07-08T10:45:40.775-07:002011-07-08T10:45:40.775-07:00I'm not a tiny code fetishist, but holy bejeez...I'm not a tiny code fetishist, but holy bejeezus SafeInt might be the most over-engineered over-sized thing I've ever seen.cbloomhttps://www.blogger.com/profile/10714564834899413045noreply@blogger.comtag:blogger.com,1999:blog-5246987755651065286.post-19449347111660369462011-07-08T09:25:24.819-07:002011-07-08T09:25:24.819-07:00SafeInt solves out-of-range errors on casting.<a href="http://safeint.codeplex.com/" rel="nofollow">SafeInt</a> solves out-of-range errors on casting.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-5246987755651065286.post-31806444547410416592011-06-24T19:02:42.493-07:002011-06-24T19:02:42.493-07:00What warning level is that?
Maybe my compilers wi...What warning level is that?<br /><br />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.won3dhttps://www.blogger.com/profile/09787472194187459747noreply@blogger.comtag:blogger.com,1999:blog-5246987755651065286.post-65932211670621043952011-06-24T18:50:16.183-07:002011-06-24T18:50:16.183-07:00main.cpp(236) : warning C4244: 'argument' ...main.cpp(236) : warning C4244: 'argument' : conversion from 'int' to 'short', possible loss of datacbloomhttps://www.blogger.com/profile/10714564834899413045noreply@blogger.comtag:blogger.com,1999:blog-5246987755651065286.post-59316879897060472922011-06-24T18:40:08.972-07:002011-06-24T18:40:08.972-07:00I tried it with gcc 4.2 -Wall (old, I know) and cl...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?<br /><br />char foo(short s) {<br /> return (char)s;<br />}<br /><br />int main() {<br /> int i = 100000;<br /> return foo(i);<br />}won3dhttps://www.blogger.com/profile/09787472194187459747noreply@blogger.comtag:blogger.com,1999:blog-5246987755651065286.post-32405959649817578312011-06-24T18:26:48.461-07:002011-06-24T18:26:48.461-07:00"U8 byte = U16toU8(some_int)
Where the int to..."U8 byte = U16toU8(some_int)<br />Where the int to U16 conversion screws you before your clamping happens."<br /><br />Yeah, but no C compiler should silently do that implicit cast ? You should get a compile warning there.cbloomhttps://www.blogger.com/profile/10714564834899413045noreply@blogger.comtag:blogger.com,1999:blog-5246987755651065286.post-71842707746581183402011-06-24T18:11:24.080-07:002011-06-24T18:11:24.080-07:00I wasn't being clear because I was talking abo...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:<br /><br />U8 byte = U16toU8(some_int)<br /><br />Where the int to U16 conversion screws you before your clamping happens.<br /><br />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:<br /><br />U8 byte = U8Clamp(some_int);<br /><br />Looks better to me.won3dhttps://www.blogger.com/profile/09787472194187459747noreply@blogger.comtag:blogger.com,1999:blog-5246987755651065286.post-53533255068412101732011-06-24T16:27:13.688-07:002011-06-24T16:27:13.688-07:00"The real problem is that you're not gett..."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."<br /><br />How's that? If it implicit casts without a warning then you should be fine (?)<br /><br /><br />On further thought I'm pretty sure that the overloaded version that leaves off the from is The Win , eg .:<br /><br />U8 byte = clampU8(some_int);<br />S16 word = checkS16(some_long);cbloomhttps://www.blogger.com/profile/10714564834899413045noreply@blogger.comtag:blogger.com,1999:blog-5246987755651065286.post-40310622864507290422011-06-24T15:08:38.310-07:002011-06-24T15:08:38.310-07:00"Maybe it would be nicer if I left off the ty..."Maybe it would be nicer if I left off the type it was casting from in the name."<br /><br />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.<br /><br />Also, ryg and others suggest that "From" names seem to be better than "To" names:<br /><br />U8 byte = U8FromS32(some_int)won3dhttps://www.blogger.com/profile/09787472194187459747noreply@blogger.comtag:blogger.com,1999:blog-5246987755651065286.post-88189000941815009362011-06-19T06:59:33.488-07:002011-06-19T06:59:33.488-07:00Sorry, I did not read the whole post but how about...Sorry, I did not read the whole post but how about using an union?<br /><br />union MultiPtr<br />{<br />char *pc;<br />short *ps;<br />};<br /><br />mptr.ps[0] = 16;<br />mptr.pc++;<br />mptr.pc[0] = 8;ejulienhttps://www.blogger.com/profile/02023427016047015709noreply@blogger.comtag:blogger.com,1999:blog-5246987755651065286.post-41330979717932504172011-06-17T18:48:30.817-07:002011-06-17T18:48:30.817-07:00Hmm.
Maybe something along the lines of casting t...Hmm.<br /><br />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.<br /><br />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...).jfbhttps://www.blogger.com/profile/11281881673668731049noreply@blogger.com