From: SourceForge.net <no...@so...> - 2005-09-11 15:24:09
|
Bugs item #730366, was opened at 2003-04-30 21:09 Message generated for change (Comment added) made by maartenbrock You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=730366&group_id=599 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: C-Front End >Group: non bugs >Status: Pending >Resolution: Rejected Priority: 2 Submitted By: Bernhard Held (bernhardheld) >Assigned to: Maarten Brock (maartenbrock) Summary: Constants exeeding 32 bits Initial Comment: float.c from the regression tests contained a constant float f = 0x100000000; // 33 bits! constVal() in SDCCval.c uses sscanf("%lx", ) to convert the value. On 32 bit platforms 0xffffffff is returned by sscanf() without any error indication. On 64 bit alpha however the constant fits in "long sval", sscanf() returns the correct value. Later 0 is assigned to v_ulong, which is perfectly correct. How can we fix this problem? Do we need to rewrite sscanf(), which throws an error, if the value exeeds 32 bits? ---------------------------------------------------------------------- >Comment By: Maarten Brock (maartenbrock) Date: 2005-09-11 17:24 Message: Logged In: YES user_id=888171 Hi, I'm willing to dive into this, but it's not clear what the problem is. When I compile the following: unsigned long a = 0x100000000; float b = 0x100000000; float c = 4294967296; float d = 4294967296.0; a, b and c are assigned 0, and d is assigned 2^32 (0x4F800000). Isn't this exactly what should be expected for a compiler that does not support 64 bit integers? So in my opinion this is not a bug. Maarten ---------------------------------------------------------------------- Comment By: Nobody/Anonymous (nobody) Date: 2003-05-01 19:08 Message: Logged In: NO >> long long is guaranteed to be 64 bits at least. >And if the constant exceeds 64 bits, we're in trouble again. >This is somewhat academic, but IMO using "long long" is not >a real fix. OK. But if you want to be able to support more than 64 bits either now or in the future then your only option is to rewrite scanf and to provide some sort of multiple precision way of storing the result. There is no portable way of storing a number >64 bits in a C integer type OTOH, if all you want is to be able to detect the overflow when it occurs then use strtol() to do the conversion. ---------------------------------------------------------------------- Comment By: Kevin Vigor (kvigor) Date: 2003-05-01 18:57 Message: Logged In: YES user_id=11484 The solution is to use strtol, which sets errno on range errors, like in this sample: #include <errno.h> #include <stdio.h> #include <stdlib.h> // Returns zero on success. int scanLong(const char *str, long *val) { errno = 0; *val = strtol(str,NULL,0); return errno != 0; } #define BUFSZ 1024 int main(void) { char buff[BUFSZ]; int rc; long val; while (1) { printf("Enter constant: "); fgets(buff, BUFSZ, stdin); rc = scanLong(buff, &val); printf("scanHexLong returns %s, val = 0x%lx, errno = %d\n", rc ? "failure" : "success", val, errno); } return 0; } I'm eyeballs deep in 400 hacking right now; I will implement this solution, eventually, if nobody else gets there first. ---------------------------------------------------------------------- Comment By: Bernhard Held (bernhardheld) Date: 2003-05-01 18:20 Message: Logged In: YES user_id=203539 > Do you use gcc exclusively for the builds? VC and bcc are used too. > long long is guaranteed to be 64 bits at least. And if the constant exceeds 64 bits, we're in trouble again. This is somewhat academic, but IMO using "long long" is not a real fix. ---------------------------------------------------------------------- Comment By: Nobody/Anonymous (nobody) Date: 2003-05-01 18:06 Message: Logged In: NO Do you use gcc exclusively for the builds? gcc supports long long (standard in C99 but gcc gives a warning if you compile with -ansi -pedantic about ISO C89 not supporting this) unsigned long long int val; scanf("%llx",&val); should be valid C99 code and is supported by gcc. long long is guaranteed to be 64 bits at least. sdcc (at) locofungus.org ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=730366&group_id=599 |