Thanks. As you might know, I have plans on changing the internal type
of json_integer to long. long long may have performance and
compatibility issues, so this patch cannot be applied to Jansson. (But
if I understood correctly, this wasn't even your intention.)
However, this shows me what needs to be done to change the internal
type of json_integer, I'll just need to replace long long with long,
and update the documentation.
Talking about 64-bit integers also made me think (again) about
supporting a bignum library, e.g. GMP. I might make a few experiments
with it at some point.
Petri
While looking at your patch a bit closer, I noticed that there are
some wrapped lines. Here's a fixed version:
---
+++ jansson-1.3.new/src/jansson_private.h 2010-08-0818:54:04.000000000 -0600
Note that on LLP64 platforms a "long" is just 32-bit while a
"long long" is 64. See
<http://www.unix.org/version2/whatsnew/lp64_wp.html>
Perhaps it may be best to abstract the types out to just the
header file; that way if anybody needs to change the
actual type for some use it would be fairly easy. At a
minimum, something like:
#ifdef _LONG_LONG
#define USE_LONG_LONG 1
#endif
#ifdef LONG_LONG_MAX
#define USE_LONG_LONG 1
#endif
#ifdef USE_LONG_LONG
typedef long long json_int;
#define JSON_INTFMT "lld"
#define JSON_STRTOINT strtoll
#else
typedef long json_int;
#define JSON_INTFMT "ld"
#define JSON_STRTOINT strtol
#endif
Of course for ISO C99 systems, there are already some
predefined macros and types which you should use
instead. So do:
#if __STDC_VERSION__ >= 199901L
#include <inttypes.h>
typedef intmax_t json_int;
#define JSON_INTFMT PRIdMAX
#define JSON_STRTOINT strtoimax
#else
...
#endif
See <http://www.opengroup.org/onlinepubs/9699919799/basedefs/inttypes.h.html>
--
Deron Meranda
http://deron.meranda.us/
Rarely if ever is there a performance hit for using 'long long' rather
than 'long', though there could be a "mild" memory hit.
It's not true the other direction though, there can be significant
performance penalties for going too small. For instance using
short rather than int. This is why the ISO C99 standard defines
portable minimal-fast integer types (e.g., int_fast16_t), but not
portable maximal-fast types.
I should also mention the hopefully obvious, the difference in
possible performance among your integer storage size choices
will most likely be insignificant for any typical use of JSON data.
Those things mostly only matter for massive number crunching,
image processing, kernel coding, etc.
The most important things to consider are:
1. It's very portable
2. It uses the largest native integer size (practically) available
to prevent overflows.
You both made me convinced. After really thinking about it, my biggest
concern was not performance but the ease of use. I wanted that even if
long long is used, it's still possible to do this:
int a = json_integer_value(foo);
... and other things like this. It seems that at least gcc doesn't
warn about assigning to smaller integer types, even with all warnings
enabled.
So, I've changed things so that the configure script detects whether
long long is available or not. json_int_t is typedef'd to either `long
long' or `long' based on this test, and it is used as the underlying
type of json_integer. Conversions to and from string have also been
changes as Deron suggested.
I still need to update the documentation. When that's done, I'll push
the change to the "next" branch in github.
I still fear that for some people even long long isn't enough... :)
Petri
None of the various compilers I have access to will ever warn
about this, even is sizeof(int) < sizeof(long).
The ISO C99 standard states that if the "larger" numeric type's
value can be represented in the smaller type's range, it is
to be implicitly and silently converted keeping the same value.
However if the value can not be represented, then it is
implementation-defined as to what happens. You could
get a bogus value, a bit-anded portion, the MAX value,
or even a runtime signal. Most compilers seem to take
the bit-and approach, simply cutting off the most significant
bits whether data loss occurs or not.
Note that this means this is a runtime issue, not a
compile-time.
I guess all that jansson should do is:
1. Warn about this in the documentation; i.e., that
integer values may be larger than 'int'.
2. Make a type definition available, e.g., json_int_t
Yes, this is exactly what I'm going to do. Thanks for the input.