c - Is this treatment of int64_t a GCC AND Clang bug? -
c - Is this treatment of int64_t a GCC AND Clang bug? -
now, of tempted shout undefined behaviour, there's problem. type int64_t
not defined c standard posix. posix defines type as:
a signed integer type width n, no padding bits, , two's-complement representation.
it not leave implementation define , not allow treated unbounded integer.
linux$ cat x.c #include <stdio.h> #include <stdlib.h> #include <inttypes.h> int stupid (int64_t a) { homecoming (a+1) > a; } int main(void) { int v; printf("%d\n", v = stupid(int64_max)); exit(v); } linux$ gcc -ox x.c -wall && ./x 0 linux$ gcc -ox x.c -wall -o2 && ./x # error. 1 linux$ gcc --version gcc (debian 4.9.2-10) 4.9.2 copyright (c) 2014 free software foundation, inc. free software; see source copying conditions. there no warranty; not merchantability or fitness particular purpose. linux$ uname -a linux localhost 3.14.13-0-amd64 #1 smp sat jul 26 20:03:23 bst 2014 x86_64 gnu/linux linux$ getconf long_bit 32 linux$
obviously, there's problem here ... it? have missed sort of implicit cast ?
you don't need go posix sort out, iso c controls particular aspect in toto (references below c11
standard).
the rest of reply going go "language lawyer" show why it's undefined behaviour add together 1 signed value , hence why both answers (true and false) valid.
first, contention int64_t
not defined in iso not correct. section 7.20.1.1 exact-width integer types
states, when referring intn_t
types, that:
the typedef name intn_t
designates signed integer type width n, no padding bits, , two’s complement representation. thus, int8_t
denotes such signed integer type width of 8 bits.
these types optional. however, if implementation provides integer types widths of 8, 16, 32, or 64 bits, no padding bits, , (for signed types) have two’s complement representation, shall define corresponding typedef names.
that's why don't need worry posix defining types in way, since iso defines them same (two's complement, no padding, etc) assuming has appropriate capabilities.
so, we've established iso does define them (if they're available in implementation), let's @ 6.5 expressions /5
:
if exceptional status occurs during evaluation of look (that is, if result not mathematically defined or not in range of representable values type), behavior undefined.
adding 2 identical integral types give same type (at to the lowest degree @ rank of int64_t
, above point integer promotions done1), since dictated usual arithmetic conversions specified in 6.3.1.8
. after section dealing various floating point types (of int64_t
not), see:
if both operands have same type, no farther conversion needed.
earlier in same section find statement dictates type of result 1 time mutual type has been found:
unless explicitly stated otherwise, mutual real type corresponding real type of result.
so, given result of int64_max+1
won't fit int64_t
variable, behaviour undefined.
based on comments encoding of int64_t
indicates adding 1 would wrap, have understand doesn't alter clause it's undefined @ all. implementation still free whatever wants in case, if doesn't create sense based on think.
and, in case, look int64_max + 1 > int64_max
(where 1
undergoes integer promotion int64_t
) may compiled 1
since that's arguably faster incrementing value , doing comparison. , is right result, since anything right result :-)
in sense, it's no different implementation converting:
int ub (int i) { homecoming i++ * i++; } // big no-no : int x = ub (3);
into simpler , faster:
int x = 0;
you may contend reply improve 9
or 12
(depending on when ++
side effects performed) but, given undefined behaviour breaking of contract between coder , compiler, compiler free whatever wants.
in case, if want well defined version of function, opt like:
int stupid (int64_t a) { homecoming (a == int64_max) ? 0 : 1; }
that gets desired/expected result without resorting undefined behaviour :-)
1 there may border case here if width of int
greater 64 bits. in case, may integer promotions forcefulness int64_t
int
, allowing look defined. haven't looked in great detail may wrong (in other words, don't consider gospel part of answer) it's worth keeping in mind check if ever implementation int
more 64 bits wide.
c linux gcc clang posix
Comments
Post a Comment