[LLVMbugs] [Bug 23404] int32_t vs. int64_t vs. long ambiguity

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Mon May 4 06:17:37 PDT 2015


https://llvm.org/bugs/show_bug.cgi?id=23404

jonathan.sauer at gmx.de changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|REOPENED                    |RESOLVED
         Resolution|---                         |INVALID

--- Comment #3 from jonathan.sauer at gmx.de ---
(In reply to comment #2)
> The behavior just seems very inconsistent. The overloads work for all signed
> integral types, except for 'long', even though there's a perfect match for
> that type (ie. std::int64_t). For example a short(123) matches std::int32_t
> without problems even though it's not even the same size. In summary:
> 
>     foo(char(123)); // Ok, matches std::int32_t
>     foo(short(123)); // Ok, matches std::int32_t

I'm guessing this is because "char" and "short" are promoted to "int", see C++
Standard §4.5 (Integral promotions).

>     foo(123); // Ok, matches std::int32_t
>     foo(123L); // Ambiguous
>     foo(123LL); // Ok, matches std::int64_t
> 
> The thing is, there seems to be no portable way of supporting all of those
> types without the calling code needing to do an explicit cast with that one
> single exception, if the interface needs to handle integers of explicit size.

There is: The macros INT32_C, UINT32_C, INT64_C, UINT64_C etc.

> Adding an overloaded version for 'long' works with clang, but will it work
> with other compilers? Potentially not. There is no way of adding an overload
> that matches 'long' without it potentially clashing with the other overloads
> in some compiler.

True. If you use the std::intXX_t types in function overloading, you must only
use those types.

> Is there an actual reason (ie. stated in the C++ standard) that a 64-bit
> 'long' can't perfectly match std::int64_t, even though both are signed
> 64-bit integers? (And, likewise, a 32-bit 'long' would match std::int32_t,
> as they are both identical.)

"long" and "int" are different types, as are "long long" and "long". They can
be implicitly converted (C++ Standard §4.7, Integral conversions), but the
conversion of "long" to "int" is as good as the conversion to "long long",
irregardless of their size (otherwise the same code would compile or not
depending on the integer sizes of the target platform). So the call of "foo"
with an argument of type "long" is ambiguous. See C++ Standard §10
(Overloading) and more specifically §13.3.3.1 (Implicit conversion sequences).

Maybe this StackOverflow question helps clarify things further:
http://stackoverflow.com/questions/10579544/

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20150504/456f7c38/attachment.html>


More information about the llvm-bugs mailing list