Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 28 Mar 2018 14:52:28 +0200
From: CodingMarkus <>
Subject: Re: Maybe not a bug but a possible omission?

> On 2018-03-28, at 12:31, Jon Scobie <> wrote:
> #define INT64_MIN  (-1-0x7fffffffffffffff)
> the equivalent glibc definition is the equivalent of
> #define INT64_MIN  (-1-0x7fffffffffffffffL)

According to ISO-C 2011 standard (page 63):

"The type of an integer constant is the first of the corresponding list in which its value can be represented.”

And for constants that have no type suffix (no “L”, “LL”, “U”, “UL”, “ULL”), the “list” mentioned above contains the following types decimal values:

int, long int, long long int

and the following types of octal/hex values:
int, unsigned int, long int, unsigned long int, long long int, unsigned long long int

Thus the type is the first one of the three above that is big enough to represent a constant value. 

By using the suffix “L”, all that happens is that the type list is further limited down to:

long int, long long int

or for octal/hex values:

long int, unsigned long int, long long int, unsigned long long int

On most systems, only long int or long long int can represent "(-1-0x7fffffffffffffff)”, so either one will be the deferred type. Appending the suffix “L” would thus not make any difference, as it will not result in a different type. It only eliminates the type “int” from the list but I don’t know any system where the type int could represent such a big number, so int is never chosen to begin with.

Personally I wonder about that definition in both libraries, I had expected it to be:

#define INT64_MIN  INT64_C(...)

because that assures the type is pinned to whatever type int64_t maps on the system. After all the C standard also says about INT64_MIN the other defines:

"Each instance of any defined macro shall be replaced by a constant expression suitable for use in #if preprocessing directives, and this expression shall have the same type as would an expression that is an object of the corresponding type converted according to the integer promotions.”

So INT64_MIN should be the same type as int64_t is (that’s how I interpret the last part of that sentence) and that is not always guaranteed when defined as above, as when defined as above, a long int is enough to represent that type on a 64 bit system (on 64 bit systems, long is typically 64 bit already), whereas int64_t may as well be a long long int on such a system. At least PRI64d typically uses “lld” AFAIK and not “ld”, though I have not checked what musl or glibc uses for PRI64d on 64 bit systems.

> The issue is that swig has no idea what type INT64_MAX is if you don't specifically state what it is so it treats it as a goint - which is not a long (or long long).

If swig fails to correctly process valid C code, then this sounds like a bug that the swig developers should really fix. The type of a numeric constant is always exactly defined by the C standard, it’s never required to give an explicit type unless you want a “wider” type than would have been chosen automatically otherwise or you want to force a signed value to be an unsigned type. Every tool parsing, compiling or processing C code should know the type rules and should apply them the same way a C compiler would do it, shouldn’t it?


Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.