Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > 64-bit integers where the implementation supports max 32-bit ints

Reply
Thread Tools

64-bit integers where the implementation supports max 32-bit ints

 
 
James Harris
Guest
Posts: n/a
 
      08-06-2013

"James Kuyper" <(E-Mail Removed)> wrote in message
news:ktqo42$i8e$(E-Mail Removed)...
> On 08/06/2013 06:15 AM, James Harris wrote:
> ...
>> It's a pity there's no such thing as a preprocessor assert to check the
>> results - and, yes, I have seen various clever but convoluted attempts to
>> make one.

>
> What does "preprocessor assert" mean to you, such that #if combined with
> #error fails to qualify?


Ah, sorry - was thinking of verifying/asserting the *sizes* of the defined
types.

James


 
Reply With Quote
 
 
 
 
James Kuyper
Guest
Posts: n/a
 
      08-06-2013
On 08/06/2013 08:59 AM, James Harris wrote:
> "James Kuyper" <(E-Mail Removed)> wrote in message
> news:ktqo42$i8e$(E-Mail Removed)...
>> On 08/06/2013 06:15 AM, James Harris wrote:
>> ...
>>> It's a pity there's no such thing as a preprocessor assert to check the
>>> results - and, yes, I have seen various clever but convoluted attempts to
>>> make one.

>>
>> What does "preprocessor assert" mean to you, such that #if combined with
>> #error fails to qualify?

>
> Ah, sorry - was thinking of verifying/asserting the *sizes* of the defined
> types.


OK - obviously that can't be done by a preprocessor assert, because
types don't exist yet, so sizeof(type) is meaningless, and is converted
into a syntax error during evaluation of #if conditions.

However, why are you interested in the sizes? I got the impression from
your previous messages that you were mainly interested in the ranges,
*_MIN to *_MAX, which are available in <limits.h> and <stdint.h>, and
are testable in #if.
--
James Kuyper
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      08-06-2013
On 8/5/2013 9:42 PM, Keith Thompson wrote:
> "James Harris" <(E-Mail Removed)> writes:
>> "Keith Thompson" <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed)...

> [...]
>> FWIW the section of the header which defines the 64-bit types is currently
>> as follows. It's not fully tested yet.
>>
>> /*
>> * 64-bit integers
>> */
>>
>> #if INT_MAX == 0x7fffffffffffffff
>> typedef signed int s64_t;
>> #elif LONG_MAX == 0x7fffffffffffffff
>> typedef signed long s64_t;
>> #elif LLONG_MAX == 0x7fffffffffffffff
>> typedef signed long long s64_t;
>> #else
>> typedef struct {u32_t low; s32_t high;} s64_t; /* Limited use */
>> #endif

>
> This might cause problems if the 16-bit compiler's preprocessor can't
> handle a 64-bit constant like 0x7fffffffffffffff. I'm not sure there's
> a really good solution. But it's likely you'll only get some warnings,
> and you can ignore them as long as it selects the right definition.
> [...]


One approach is to write tests like

#if ((INT_MAX >> 16) >> 16) == 0x7fffffff

Details: We know that preprocessor arithmetic is equivalent to that
of the execution environment's widest integer types, which are no
narrower than `[unsigned] long', which are at least 32 bits wide.
Therefore, the 16-bit shifts above are well-defined (although a
31-bit shift of a signed value might not be), and two of them
eliminate 32 low-order bits. Also, we know that INT_MAX is one
less than a power of two, so if any 1-bits remain after shifting
we can conclude that all the eliminated bits were also 1's.

Similar arrangements like

#if ((INT_MAX >> 30) >> 30) == 0x7

would also work, in pretty much the same way.

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)d
 
Reply With Quote
 
James Harris
Guest
Posts: n/a
 
      08-06-2013

"James Kuyper" <(E-Mail Removed)> wrote in message
news:ktqtfq$fkb$(E-Mail Removed)...
> On 08/06/2013 08:59 AM, James Harris wrote:
>> "James Kuyper" <(E-Mail Removed)> wrote in message
>> news:ktqo42$i8e$(E-Mail Removed)...
>>> On 08/06/2013 06:15 AM, James Harris wrote:
>>> ...
>>>> It's a pity there's no such thing as a preprocessor assert to check the
>>>> results - and, yes, I have seen various clever but convoluted attempts
>>>> to
>>>> make one.
>>>
>>> What does "preprocessor assert" mean to you, such that #if combined with
>>> #error fails to qualify?

>>
>> Ah, sorry - was thinking of verifying/asserting the *sizes* of the
>> defined
>> types.

>
> OK - obviously that can't be done by a preprocessor assert, because
> types don't exist yet, so sizeof(type) is meaningless, and is converted
> into a syntax error during evaluation of #if conditions.
>
> However, why are you interested in the sizes? I got the impression from
> your previous messages that you were mainly interested in the ranges,
> *_MIN to *_MAX, which are available in <limits.h> and <stdint.h>, and
> are testable in #if.


Not quite. I am *using* the ranges in limits.h to define the sizes of
various signed and unsigned integers, namely:

[su]8_t
[su]16_t
[su]32_t
[su]64_t

The idea is that these can be used in the code in their own right (not all
of my compilers have stdint.h but the project requires a lot of
specific-sized integers) and can also be used elsewhere in headers to set
the sizes of other integers needed in the project.

In terms of the 'preprocessor assert' issue I was thinking it would be a
good idea to verify that they were all the expected sizes. ATM I verify them
by running some code as in

$ ./a.out
sizeof s8_t 1
sizeof u8_t 1
sizeof s16_t 2
sizeof u16_t 2
sizeof s32_t 4
sizeof u32_t 4
sizeof s64_t 8
sizeof u64_t 8
sizeof sint_t 8
sizeof uint_t 8
sizeof bptr_t 8

The above set is for the 64-bit target which is why [su]int_t have size 8.
(I believe gcc defaults to 4 byte ints on 64-bit targets.) The last one,
bptr_t is for byte pointers.

James


 
Reply With Quote
 
Malcolm McLean
Guest
Posts: n/a
 
      08-06-2013
On Tuesday, August 6, 2013 3:12:47 PM UTC+1, James Harris wrote:
> "James Kuyper" <(E-Mail Removed)> wrote in message
>
> sizeof sint_t 8
>
> sizeof uint_t 8
>
> The above set is for the 64-bit target which is why [su]int_t have size 8.
> (I believe gcc defaults to 4 byte ints on 64-bit targets.)
>

int should be the natural register size, which means 64 bits on a 64 bit
system. That also means that, expect for the annoying but practically
unimportant case of a byte array that takes up over half the memory,
int can index any array.

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-06-2013
"James Harris" <(E-Mail Removed)> writes:
> "Keith Thompson" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...

[...]
>> For example:
>>
>> #if _STDC_VERSION__ >= 199901L
>> #include <stdint.h>
>> #else
>> #include <mystdint.h>
>> #endif
>>
>> You can then freely use uint32_t and friends (except, of course, that
>> your uint64_t won't directly support arithmetic operations).

>
> AIUI both <> and "" refer to implementation-defined places but wouldn't the
> above normally have mystdint.h in quotes rather than angle brackets?


Yes, I should have written #include "mystdint.h".

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-06-2013
Malcolm McLean <(E-Mail Removed)> writes:
> On Tuesday, August 6, 2013 3:12:47 PM UTC+1, James Harris wrote:
>> "James Kuyper" <(E-Mail Removed)> wrote in message
>>
>> sizeof sint_t 8
>>
>> sizeof uint_t 8
>>
>> The above set is for the 64-bit target which is why [su]int_t have size 8.
>> (I believe gcc defaults to 4 byte ints on 64-bit targets.)
>>

> int should be the natural register size, which means 64 bits on a 64 bit
> system. That also means that, expect for the annoying but practically
> unimportant case of a byte array that takes up over half the memory,
> int can index any array.


Perhaps it "should". Nevertheless, int is typically 32 bits on 64-bit
systems, probably because making it 64 bits would mean you can't have
both a 16-bit type and a 32-bit type (unless the implementation resorts
to extended integer types).

Perhaps it would have made sense to add a "short short" type, so you
could have:
char 8 bits
short short 16 bits
short 32 bits
int 64 bits
but I don't see that happening any time soon.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      08-06-2013
On 08/06/2013 10:12 AM, James Harris wrote:
> "James Kuyper" <(E-Mail Removed)> wrote in message
> news:ktqtfq$fkb$(E-Mail Removed)...

....
>> However, why are you interested in the sizes? I got the impression from
>> your previous messages that you were mainly interested in the ranges,
>> *_MIN to *_MAX, which are available in <limits.h> and <stdint.h>, and
>> are testable in #if.

>
> Not quite. I am *using* the ranges in limits.h to define the sizes of
> various signed and unsigned integers, namely:
>
> [su]8_t
> [su]16_t
> [su]32_t
> [su]64_t
>
> The idea is that these can be used in the code in their own right (not all
> of my compilers have stdint.h but the project requires a lot of
> specific-sized integers) and can also be used elsewhere in headers to set
> the sizes of other integers needed in the project.
>
> In terms of the 'preprocessor assert' issue I was thinking it would be a
> good idea to verify that they were all the expected sizes. ...


Well, pre-processing is translation phase 4; types don't exist, and
therefore don't have a size, until translation phase 7, so you're
looking for something that occurs later than pre-processing, but earlier
than assert() itself. C2011 provides _Static_assert() for that purpose,
but if you can't even count on support for stdint.h, I guess you can't
use _Static_assert().
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      08-06-2013
"James Harris" <(E-Mail Removed)> writes:

> "James Kuyper" <(E-Mail Removed)> wrote in message
> news:ktqtfq$fkb$(E-Mail Removed)...
>> On 08/06/2013 08:59 AM, James Harris wrote:
>>> "James Kuyper" <(E-Mail Removed)> wrote in message
>>> news:ktqo42$i8e$(E-Mail Removed)...
>>>> On 08/06/2013 06:15 AM, James Harris wrote:
>>>> ...
>>>>> It's a pity there's no such thing as a preprocessor assert to check the
>>>>> results - and, yes, I have seen various clever but convoluted attempts
>>>>> to
>>>>> make one.
>>>>
>>>> What does "preprocessor assert" mean to you, such that #if combined with
>>>> #error fails to qualify?
>>>
>>> Ah, sorry - was thinking of verifying/asserting the *sizes* of the
>>> defined
>>> types.

>>
>> OK - obviously that can't be done by a preprocessor assert, because
>> types don't exist yet, so sizeof(type) is meaningless, and is converted
>> into a syntax error during evaluation of #if conditions.
>>
>> However, why are you interested in the sizes? I got the impression from
>> your previous messages that you were mainly interested in the ranges,
>> *_MIN to *_MAX, which are available in <limits.h> and <stdint.h>, and
>> are testable in #if.

>
> Not quite. I am *using* the ranges in limits.h to define the sizes of
> various signed and unsigned integers, namely:
>
> [su]8_t
> [su]16_t
> [su]32_t
> [su]64_t
>
> The idea is that these can be used in the code in their own right (not all
> of my compilers have stdint.h but the project requires a lot of
> specific-sized integers) and can also be used elsewhere in headers to set
> the sizes of other integers needed in the project.
>
> In terms of the 'preprocessor assert' issue I was thinking it would be a
> good idea to verify that they were all the expected sizes. ATM I verify them
> by running some code as in


You can get a compile-time check by writing code that generates a
constraint violation based on the size. There are lots of options and I
am not sure there is any definitive "best practice" way to do it. Hers
is just one:

#define SA_JOIN(a, b, c) a##b##c
#define SA_ID(p, l, s) SA_JOIN(p, l, s)
#define STATIC_ASSERT(b) \
struct SA_ID(assert_on_, __LINE__, _struct) { \
int SA_ID(assert_on_line_, __LINE__, _failed) : !!(b); \
}

STATIC_ASSERT(sizeof(int) == 4);
STATIC_ASSERT(sizeof(int) == 5);

You can't guarantee good messages, but you will get something from the
compiler. Reasonable ones will fail to compile (rather than just warn)
when given a zero width bit-field. gcc says:

t.c:9:1: error: zero width for bit-field 'assert_on_line_9_failed'

<snip>
--
Ben.
 
Reply With Quote
 
Stephen Sprunk
Guest
Posts: n/a
 
      08-07-2013
On 06-Aug-13 09:19, Malcolm McLean wrote:
> On Tuesday, August 6, 2013 3:12:47 PM UTC+1, James Harris wrote:
>> sizeof sint_t 8
>> sizeof uint_t 8
>>
>> The above set is for the 64-bit target which is why [su]int_t have
>> size 8. (I believe gcc defaults to 4 byte ints on 64-bit targets.)

>
> int should be the natural register size, which means 64 bits on a 64
> bit system.


Of course, that assumes a useful definition of "natural". For instance,
there are three common models for "64-bit" machines: ILP64, I32LP64 and
IL32LLP64. And proponents of each will explain why their model is more
"natural" than the others.

> That also means that, expect for the annoying but practically
> unimportant case of a byte array that takes up over half the memory,
> int can index any array.


That assumes an int is as wide as a void*, which is not true on I32LP64
and IL32LLP64 systems, e.g. Linux and Windows on x86-64.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
The node.js Community is Quietly Changing the Face of Open Source Rodrick Brown Python 2 04-17-2013 04:47 PM
Is there a difference between the use of the word montage vscollage Danny D. Digital Photography 8 04-15-2013 02:24 PM
Windows 8 - so bad it's hastening the death of the PC? ~misfit~ NZ Computing 18 04-15-2013 04:15 AM
Iterator Question for map of ints to set of ints uclamathguy@gmail.com C++ 3 04-03-2005 03:26 AM
ints ints ints and ints Skybuck Flying C Programming 24 07-10-2004 04:48 AM



Advertisments