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

Popular posts from this blog

java - How to set log4j.defaultInitOverride property to false in jboss server 6 -

c - GStreamer 1.0 1.4.5 RTSP Example Server sends 503 Service unavailable -

Using ajax with sonata admin list view pagination -