[cfe-dev] LibC++ v3.8 - Problems with ISO C wrapper headers

David Chisnall via cfe-dev cfe-dev at lists.llvm.org
Mon Jan 25 01:37:38 PST 2016


On 23 Jan 2016, at 22:23, Martin J. O'Riordan via cfe-dev <cfe-dev at lists.llvm.org> wrote:
> 
>> The effective code subtly changes silently from:
>>  
>> int x = abs((int)aBar.operator double());  // choosing ‘int ::abs(int)’
>> to:
>> int x = (int)abs(aBar.operator double());  // choosing ‘double ::abs(double)’
> Of all of your examples, this is the most important. The other changes result in a compilation failure, and are easy to fix. However, it is certainly my experience that, in almost all cases, the semantic change you highlight is actually a silent bug *fix*, as the author almost always intended the behavior we now have, not the behavior we provided previously. Obviously this will not be 100% true, but on balance, the change has seems positive. Either way, good compiler warnings are essential. As I recall, Clang does have a good warning for this.

A little while ago, on FreeBSD we rewrote some of the [tg]math.h macros.  The old versions used sizeof(arg) == sizeof({float,double,long double}) to select the versions.  The new versions to use _Generic (with fallback __builtin_type_select and fallback to sizeof).  Unlike C++ overloading, _Generic does not permit implicit conversion.  We found (and reported / fixed) several issues that were real bugs in people’s code that had been silently returning the wrong value on other platforms (and older versions of FreeBSD) for years.

Implicit casts are probably the most dangerous misfeature to ever end up in mainstream programming languages, or at least in the top three with arbitrary pointer arithmetic and null-terminated strings.

David




More information about the cfe-dev mailing list