Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Suitable type names needed for portable integers

Reply
Thread Tools

Suitable type names needed for portable integers

 
 
James Harris
Guest
Posts: n/a
 
      08-15-2013
I am working on code that is to run on 16-bit, 32-bit and 64-bit machines
and am looking for a way to declare specific types of integers. Could you
suggest suitable names for the following?

1. Integers which will be 16-bit on 16-bit machines and 32-bit on both
32-bit machines and 64-bit machines.

2. Integers which will be 16-bit on 16-bit machines, 32-bit on 32-bit
machines and 64-bit on 64-bit machines.

Both of these types need at least signed and unsigned variants so the need
is for exactly four type names:

a name for signed 16, 32, 32
a name for unsigned 16, 32, 32

a name for signed 16, 32, 64
a name for unsigned 16, 32, 64

I intend to define these names explicitly so that they are not subject to
the defaults of any given compiler. So I don't want to use int, for example.
I was going to use sint and uint as two of the names but one compiler
predefines uint ... which is a pain. So I am looking for something else. All
that's needed are four names. Any suggestions? Any precedent?

James


 
Reply With Quote
 
 
 
 
James Kuyper
Guest
Posts: n/a
 
      08-15-2013
On 08/15/2013 05:34 PM, James Harris wrote:
> I am working on code that is to run on 16-bit, 32-bit and 64-bit machines
> and am looking for a way to declare specific types of integers. Could you
> suggest suitable names for the following?
>
> 1. Integers which will be 16-bit on 16-bit machines and 32-bit on both
> 32-bit machines and 64-bit machines.
>
> 2. Integers which will be 16-bit on 16-bit machines, 32-bit on 32-bit
> machines and 64-bit on 64-bit machines.
>
> Both of these types need at least signed and unsigned variants so the need
> is for exactly four type names:
>
> a name for signed 16, 32, 32
> a name for unsigned 16, 32, 32
>
> a name for signed 16, 32, 64
> a name for unsigned 16, 32, 64
>
> I intend to define these names explicitly so that they are not subject to
> the defaults of any given compiler. So I don't want to use int, for example.
> I was going to use sint and uint as two of the names but one compiler
> predefines uint ... which is a pain. So I am looking for something else. All
> that's needed are four names. Any suggestions? Any precedent?


I suspect that you've made a decision about how to achieve a goal, and
are trying to figure out how to implement that decision, when what you
really should be doing is reconsidering that decision. I suspect I could
recommend a better way of achieving that goal, if I knew what it was. So
far, you've described your decision, but not the goal it's intended to
achieve.

The <stdint.h> header that was added in C99 provides three pairs of
families of type names: [u]intN_t, [u]int_leastN_t, and [u]int_fastN_t.

For example, int_fast16_t is the fastest signed integer type that has at
least 16 bits. uint_least32_t is the smallest unsigned integer type
that has at least 32 bits. int64_t is an signed integer type with
exactly 64 bits.
The "least" and "fast" types are required to be supported for N=8, 16,
32, and 64. The exact-sized types are optional. The relevant names are
reserved for all values of N - you're not likely to need int_least39_t,
but if you find a implementation that uses that name, they're required
to use it to describe the smallest type with at least 39 bits.
You can determine which of the optional types is supported by using, for
example:

#ifdef INT32_MAX

Would any of these types serve your purpose? Note that, in particular,
int_fast16_t could be a 64 bit type on a 64 bit machine.


 
Reply With Quote
 
 
 
 
James Harris
Guest
Posts: n/a
 
      08-16-2013
"James Kuyper" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On 08/15/2013 05:34 PM, James Harris wrote:
>> I am working on code that is to run on 16-bit, 32-bit and 64-bit machines
>> and am looking for a way to declare specific types of integers. Could you
>> suggest suitable names for the following?
>>
>> 1. Integers which will be 16-bit on 16-bit machines and 32-bit on both
>> 32-bit machines and 64-bit machines.
>>
>> 2. Integers which will be 16-bit on 16-bit machines, 32-bit on 32-bit
>> machines and 64-bit on 64-bit machines.
>>
>> Both of these types need at least signed and unsigned variants so the
>> need
>> is for exactly four type names:
>>
>> a name for signed 16, 32, 32
>> a name for unsigned 16, 32, 32
>>
>> a name for signed 16, 32, 64
>> a name for unsigned 16, 32, 64
>>
>> I intend to define these names explicitly so that they are not subject to
>> the defaults of any given compiler. So I don't want to use int, for
>> example.
>> I was going to use sint and uint as two of the names but one compiler
>> predefines uint ... which is a pain. So I am looking for something else.
>> All
>> that's needed are four names. Any suggestions? Any precedent?

>
> I suspect that you've made a decision about how to achieve a goal, and
> are trying to figure out how to implement that decision, when what you
> really should be doing is reconsidering that decision. I suspect I could
> recommend a better way of achieving that goal, if I knew what it was. So
> far, you've described your decision, but not the goal it's intended to
> achieve.


It's no secret. I'll try to explain the main points briefly. The code is for
an operating system that will run on different machines - x86 and otherwise.
I am in the process of moving development from assembly to C and wanting to
take advantage of the resulting ability to compile the code for different
target machines. That's the biggest thing C gives me over assembly, i.e. the
ability to write source code once and have it compile to different forms of
machine code.

For example, I should be able to write a device driver or a memory manager
in C and have it run on an x86 whether that machine is running in 16-bit
mode, 32-bit mode or 64-bit mode. Therefore I have specific requirements
over how wide certain integers are, as follows.

Some integer sizes are mandated by the data they represent - for example,
data read from a 16-bit port might have to be 16-bit unsigned reardless of
the CPU's mode (16-, 32- or 64-bit) - and I have specific types for those as
not all compilers supported stdints. That stuff is done. But there are other
integers that can or should be the appropriate size for the target mode. For
example, some processor or OS tables hold 32-bit entries in 32-bit mode and
64-bit entries in 64-bit mode but other tables hold 32-bit entries in either
mode. Both may use 16-bit entries in 16-bit mode. So, as I say, I have some
very specific requirements for integer sizes.

Additionally (and sorry for the detail but you did ask) in 64-bit mode there
are some cases where 64-bit integers are required and others where 64-bit
integers could be used but 32-bit integers would be better. Hence I was
asking about a suitable name for integers that would be 16, 32 and 32 wide
and another name for integers that would be 16, 32 and 64 wide.

Does that explain enough to make sense of the original query?

> The <stdint.h> header that was added in C99 provides three pairs of
> families of type names: [u]intN_t, [u]int_leastN_t, and [u]int_fastN_t.
>
> For example, int_fast16_t is the fastest signed integer type that has at
> least 16 bits. uint_least32_t is the smallest unsigned integer type
> that has at least 32 bits. int64_t is an signed integer type with
> exactly 64 bits.
> The "least" and "fast" types are required to be supported for N=8, 16,
> 32, and 64. The exact-sized types are optional. The relevant names are
> reserved for all values of N - you're not likely to need int_least39_t,
> but if you find a implementation that uses that name, they're required
> to use it to describe the smallest type with at least 39 bits.
> You can determine which of the optional types is supported by using, for
> example:
>
> #ifdef INT32_MAX
>
> Would any of these types serve your purpose? Note that, in particular,
> int_fast16_t could be a 64 bit type on a 64 bit machine.


Thanks for the suggestions. The goal is different but I could possibly use a
similar principle. For the case in point the number of bits should not be
specified but some suffix on the word "int" might be appropriate. Possibly
something like these for unsigned integers in the three modes

uint_small: which becomes 16, 32, or 32
uint_large: which becomes 16, 32, or 64

That conveys the idea but at the moment those suffixes do not seem ideal. As
the integers would only differ in 64-bit mode _small and _large seem a
little incongruous in the other modes. (Remember that the source would use
those names regardles of the mode the code will run in.) I'll give it some
more thought but this seems like a good road to go down.

James


 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      08-16-2013
"James Harris" <(E-Mail Removed)> wrote in message
news:kujhhj$i1t$(E-Mail Removed)...

> 1. Integers which will be 16-bit on 16-bit machines and 32-bit on both
> 32-bit machines and 64-bit machines.
>
> 2. Integers which will be 16-bit on 16-bit machines, 32-bit on 32-bit
> machines and 64-bit on 64-bit machines.
>
> Both of these types need at least signed and unsigned variants so the need
> is for exactly four type names:
>
> a name for signed 16, 32, 32
> a name for unsigned 16, 32, 32
>
> a name for signed 16, 32, 64
> a name for unsigned 16, 32, 64
>
> I intend to define these names explicitly so that they are not subject to
> the defaults of any given compiler. So I don't want to use int, for
> example. I was going to use sint and uint as two of the names but one
> compiler predefines uint ... which is a pain. So I am looking for
> something else.


C makes treats upper and lower case variations of a name distinctly. So you
could use SINT (or INT or Int) and UINT.

I have also used 'word' to mean unsigned, leaving 'int' to mean signed (I
think 'int' is always signed unless you add 'unsigned').

With the type that's capped at 32-bits, what is the purpose of that? Perhaps
they could be given a more relevant name than just an 'int'-based one.

Also, is the 'uint' of that compiler a macro? I thought you could override
macro names. Actually I think you can override built-in names too for that
matter:

#define int int32_t

But use with some care...

--
Bartc

 
Reply With Quote
 
James Harris
Guest
Posts: n/a
 
      08-16-2013
"BartC" <(E-Mail Removed)> wrote in message
news:L6lPt.4712$(E-Mail Removed)4...
> "James Harris" <(E-Mail Removed)> wrote in message
> news:kujhhj$i1t$(E-Mail Removed)...
>
>> 1. Integers which will be 16-bit on 16-bit machines and 32-bit on both
>> 32-bit machines and 64-bit machines.
>>
>> 2. Integers which will be 16-bit on 16-bit machines, 32-bit on 32-bit
>> machines and 64-bit on 64-bit machines.
>>
>> Both of these types need at least signed and unsigned variants so the
>> need is for exactly four type names:
>>
>> a name for signed 16, 32, 32
>> a name for unsigned 16, 32, 32
>>
>> a name for signed 16, 32, 64
>> a name for unsigned 16, 32, 64
>>
>> I intend to define these names explicitly so that they are not subject to
>> the defaults of any given compiler. So I don't want to use int, for
>> example. I was going to use sint and uint as two of the names but one
>> compiler predefines uint ... which is a pain. So I am looking for
>> something else.

>
> C makes treats upper and lower case variations of a name distinctly. So
> you could use SINT (or INT or Int) and UINT.
>
> I have also used 'word' to mean unsigned, leaving 'int' to mean signed (I
> think 'int' is always signed unless you add 'unsigned').



Yes, sint is a bit ugly. At least it's less familar. It has three
advantages, though. First, as long as use of int is banned the use of sint
or uint forces me to think about what type of integer is needed at each
point. Unsigned ints - especially small ones - are suprisingly common in the
stuff I am working with. Second, the names are both the same size so
declarations naturally line up. And third, it makes source easier to search
for the specific types. Otherwise, uints also show up when searching for
ints.

> With the type that's capped at 32-bits, what is the purpose of that?


Please take a look at my reply to James Kuyper.

> Perhaps they could be given a more relevant name than just an 'int'-based
> one.


Maybe. Christian made the same point. I already do that in one or two cases
and will probably do it in some others but if I did it in all cases the
number of such names could get unfeasibly large. That would make the code
confusing, especially in places where such integers get combined with each
other - which does happen. There are simply some cases where the generic "an
integer" is what we want to say.

> Also, is the 'uint' of that compiler a macro? I thought you could override
> macro names. Actually I think you can override built-in names too for that
> matter:


Surprisingly it isn't in either of the 16-bit C compilers which I normally
expect to give me trouble but crops up in gcc. The file in question is

/usr/include/i386-linux-gnu/sys/types.h

The relevant section is

#ifdef __USE_MISC
/* Old compatibility names for C types. */
typedef unsigned long int ulong;
typedef unsigned short int ushort;
typedef unsigned int uint;
#endif

James


 
Reply With Quote
 
James Harris
Guest
Posts: n/a
 
      08-16-2013

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On Friday, August 16, 2013 1:51:35 AM UTC+1, James Harris wrote:
>> For example, some processor or OS tables hold 32-bit entries in 32-bit
>> mode and
>> 64-bit entries in 64-bit mode but other tables hold 32-bit entries in
>> either
>> mode. Both may use 16-bit entries in 16-bit mode. So, as I say, I have
>> some
>> very specific requirements for integer sizes.

>
> So you have a typedef ... thisTableIndex and another typedef ...
> thatTableIndex.
>
> You want a type that is suitable for holding an index into a certain
> table, so just call it that.


These are entries, not indices.

And the point is the other way round from your suggestion. If I followed the
principle of what you say and used different names such as thisTableEntry
and thatTableEntry I would have to use different source code. That's not
good. Instead, where practical I would rather have one type name such as
TableEntry and make it suitable for the environment which is being built
for.

James


 
Reply With Quote
 
Malcolm McLean
Guest
Posts: n/a
 
      08-16-2013
On Thursday, August 15, 2013 10:34:43 PM UTC+1, James Harris wrote:
>
>
> 2. Integers which will be 16-bit on 16-bit machines, 32-bit on 32-bit
> machines and 64-bit on 64-bit machines.
>

size_t and ssize_t may be acceptable here.
Maximum object size almost always equals 2^width of address bus = processing
register width. Not always of course. It depends if it has to work absolutely
everywhere. But there's no totally portable solution, because C can't guarantee
that "a 64 bit machine" actually means anything on some architecture someone
could invent.
 
Reply With Quote
 
James Harris
Guest
Posts: n/a
 
      08-16-2013
"Malcolm McLean" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On Thursday, August 15, 2013 10:34:43 PM UTC+1, James Harris wrote:
>>
>>
>> 2. Integers which will be 16-bit on 16-bit machines, 32-bit on 32-bit
>> machines and 64-bit on 64-bit machines.
>>

> size_t and ssize_t may be acceptable here.
> Maximum object size almost always equals 2^width of address bus =
> processing
> register width. Not always of course. It depends if it has to work
> absolutely
> everywhere. But there's no totally portable solution, because C can't
> guarantee
> that "a 64 bit machine" actually means anything on some architecture
> someone
> could invent.


Yes, I could use int for the shorter (16 32 32) variant and ssize_t for the
longer (16 32 64) at least with the compilers I am using at the moment.
However, I have an almost instinctive distrust that such names can be relied
on to do the expected thing on all compilers. I've had a number of occasions
where something that worked well on one compiler failed to do what I wanted
on another. And such differences may not be picked up at compile time. That
kind of bug can be hard to find.

So I currently define all the types I need explicitly and avoid names that
compilers might use. If you don't mind or are interested I'll post the full
setup below. Maybe someone has suggestions to improve this. At least it will
explain the bigger picture. Asbestos pants on!

For x86 there are four directories as follows

src/comn
src/x86_16
src/x86_32
src/x86_64

Each of the x86_NN directories has a file called os_bits_log2.h. Aside from
#ifdefs etc and comments those three files have exactly one line. Their
contents are, respectively, nothing more than

#define OS_BITS_LOG2 4
#define OS_BITS_LOG2 5
#define OS_BITS_LOG2 6

These are saying that for a 16-bit target the log2 of the number of bits is
4 and 2 ** 4 is 16 and similar for the other widths.

The common directory (src/comn) includes a file called os_bits.h which is as
follows:

#ifndef OS_BITS_H
#define OS_BITS_H

#include "os_bits_log2.h"

#define OS_BITS (1 << OS_BITS_LOG2) /* 16, 32 or 64 */
#define OS_BYTES (OS_BITS >> 3) /* 2, 4 or 8 */

#endif

A build of a 16-bit system will set the include directories up in this
order: first, src/x86_16, second src/comn. Similar for 32-bit and 64-bit
builds. A makefile matches compiler, switches and include paths.

Still with me?

The above sets up OS_BITS. That is used toward the end of the main types
header which is called os_types.h. Its current incarnation is below. As I
say, I would welcome an expert view of this. Even if there are no comments
this does serve to illustrate the approach I am currently taking. I may
change it. This is fairly new stuff to me but so far it seems to work well.

James

#ifndef OS_TYPES_H
#define OS_TYPES_H

#include "os_bits.h"
#include <limits.h>

/* We need to define

si8 and ui8
si16 and ui16
si32 and ui32
si64 and ui64
si_small and ui_small (32-bit on 64-bit machines)
si_large and ui_large (64-bit on 64-bit machines)
*/

/*
* Define 8-bit integers
*/

#if SCHAR_MAX == 0x7f
typedef signed char si8;
typedef unsigned char ui8;
#define si8_FMT_DEC "i"
#define ui8_FMT_DEC "u"
#else
#error "No type candidate for si8 and ui8"
#endif

/*
* 16-bit integers
*/

#if INT_MAX == 0x7fff
typedef signed int si16;
typedef unsigned int ui16;
#define si16_FMT_DEC "i"
#define ui16_FMT_DEC "u"
#elif SHRT_MAX == 0x7fff
typedef signed short si16;
typedef unsigned short ui16;
#define si16_FMT_DEC "i"
#define ui16_FMT_DEC "u"
#else
#error "No type candidate for si16 and ui16"
#endif

/*
* 32-bit integers
*/

/* Using small shifts to stop Open Watcom compiler warning */
#if (INT_MAX >> 8 >> == 0x7fff
typedef signed int si32;
typedef unsigned int ui32;
#define si32_FMT_DEC "i"
#define ui32_FMT_DEC "u"
#elif (LONG_MAX >> 16) == 0x7fff
typedef signed long si32;
typedef unsigned long ui32;
#define si32_FMT_DEC "li"
#define ui32_FMT_DEC "lu"
#else
#error "No type candidate for si32 and ui32"
#endif

/*
* 64-bit integers
*/

/* Using small shifts to stop Open Watcom compiler warning */
#if (INT_MAX >> 8 >> 8 >> 8 >> 8 >> 8 >> == 0x7fff
typedef signed int si64;
typedef unsigned int ui64;
#define si64_FMT_DEC "i"
#define ui64_FMT_DEC "u"
#elif (((LONG_MAX >> 16) >> 16) >> 16) == 0x7fff
typedef signed long si64;
typedef unsigned long ui64;
#define si64_FMT_DEC "li"
#define ui64_FMT_DEC "lu"
#elif (((LLONG_MAX >> 16) >> 16) >> 16) == 0x7fff
typedef signed long long si64;
typedef unsigned long long ui64;
#define si64_FMT_DEC "lli"
#define ui64_FMT_DEC "llu"
#else
typedef struct {ui32 low; si32 high;} si64; /* Limited use */
typedef struct {ui32 low; ui32 high;} ui64; /* Limited use */
/* #warning "Using structures for si64 and ui64" */
#define si64_FMT_DEC "%(unprintable %x)"
#define ui64_FMT_DEC "%(unprintable %x)"
#endif

/*
* Define the potential number of digits when printed
*/

#define si8_DIG_DEC 3
#define ui8_DIG_DEC 3

#define si16_DIG_DEC 5
#define ui16_DIG_DEC 5

#define si32_DIG_DEC 10
#define ui32_DIG_DEC 10

#define si64_DIG_DEC 19
#define ui64_DIG_DEC 20

/*
* Define small and large integer types. These are normally the same but
* on at least x86_64 the small integers are half the normal width. Use
* large ints by default. Use small ones only where it is known that
* large ints are unnecessary.
*/

#if OS_BITS == 16
typedef si16 si_small;
typedef ui16 ui_small;
#define si_small_MAX 0x7fff
#define ui_small_MAX 0xffffU
#define si_small_DIG_DEC si16_DIG_DEC
#define ui_small_DIG_DEC ui16_DIG_DEC
#define si_small_FMT_DEC si16_FMT_DEC
#define ui_small_FMT_DEC ui16_FMT_DEC

typedef si16 si_large;
typedef ui16 ui_large;
#define si_large_MAX 0x7fff
#define ui_large_MAX 0xffffU
#define si_large_DIG_DEC si16_DIG_DEC
#define ui_large_DIG_DEC ui16_DIG_DEC
#define si_large_FMT_DEC si16_FMT_DEC
#define ui_large_FMT_DEC ui16_FMT_DEC

#elif OS_BITS == 32
typedef si32 si_small;
typedef ui32 ui_small;
#define si_small_MAX (0x7fffffff)
#define ui_small_MAX (0xffffffffU)
#define si_small_DIG_DEC si32_DIG_DEC
#define ui_small_DIG_DEC ui32_DIG_DEC
#define si_small_FMT_DEC si32_FMT_DEC
#define ui_small_FMT_DEC ui32_FMT_DEC

typedef si32 si_large;
typedef ui32 ui_large;
#define si_large_MAX (0x7fffffff)
#define ui_large_MAX (0xffffffffU)
#define si_large_DIG_DEC si32_DIG_DEC
#define ui_large_DIG_DEC ui32_DIG_DEC
#define si_large_FMT_DEC si32_FMT_DEC
#define ui_large_FMT_DEC ui32_FMT_DEC

#elif OS_BITS == 64
typedef si32 si_small;
typedef ui32 ui_small;
#define si_small_MAX (0x7fffffff)
#define ui_small_MAX (0xffffffffU)
#define si_small_DIG_DEC si32_DIG_DEC
#define ui_small_DIG_DEC ui32_DIG_DEC
#define si_small_FMT_DEC si32_FMT_DEC
#define ui_small_FMT_DEC ui32_FMT_DEC

typedef si64 si_large;
typedef ui64 ui_large;
#define si_large_MAX (0x7fffffffffffffff)
#define ui_large_MAX (0xffffffffffffffffU)
#define si_large_DIG_DEC si64_DIG_DEC
#define ui_large_DIG_DEC ui64_DIG_DEC
#define si_large_FMT_DEC si64_FMT_DEC
#define ui_large_FMT_DEC ui64_FMT_DEC

#else
#error "OS bit width not correctly specified"
#endif


/*
* Time stamp counter type
*/

typedef ui64 tsc64;
typedef ui32 tsc32;

#endif





 
Reply With Quote
 
James Harris
Guest
Posts: n/a
 
      08-16-2013
"David Brown" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On 16/08/13 02:51, James Harris wrote:
>> "James Kuyper" <(E-Mail Removed)> wrote in message
>> news:(E-Mail Removed)...
>>> On 08/15/2013 05:34 PM, James Harris wrote:
>>>> I am working on code that is to run on 16-bit, 32-bit and 64-bit
>>>> machines
>>>> and am looking for a way to declare specific types of integers. Could
>>>> you
>>>> suggest suitable names for the following?
>>>>
>>>> 1. Integers which will be 16-bit on 16-bit machines and 32-bit on both
>>>> 32-bit machines and 64-bit machines.
>>>>
>>>> 2. Integers which will be 16-bit on 16-bit machines, 32-bit on 32-bit
>>>> machines and 64-bit on 64-bit machines.
>>>>
>>>> Both of these types need at least signed and unsigned variants so the
>>>> need
>>>> is for exactly four type names:
>>>>
>>>> a name for signed 16, 32, 32
>>>> a name for unsigned 16, 32, 32
>>>>
>>>> a name for signed 16, 32, 64
>>>> a name for unsigned 16, 32, 64
>>>>
>>>> I intend to define these names explicitly so that they are not subject
>>>> to
>>>> the defaults of any given compiler. So I don't want to use int, for
>>>> example.
>>>> I was going to use sint and uint as two of the names but one compiler
>>>> predefines uint ... which is a pain. So I am looking for something
>>>> else.
>>>> All
>>>> that's needed are four names. Any suggestions? Any precedent?
>>>
>>> I suspect that you've made a decision about how to achieve a goal, and
>>> are trying to figure out how to implement that decision, when what you
>>> really should be doing is reconsidering that decision. I suspect I could
>>> recommend a better way of achieving that goal, if I knew what it was. So
>>> far, you've described your decision, but not the goal it's intended to
>>> achieve.

>>
>> It's no secret. I'll try to explain the main points briefly. The code is
>> for
>> an operating system that will run on different machines - x86 and
>> otherwise.
>> I am in the process of moving development from assembly to C and wanting
>> to
>> take advantage of the resulting ability to compile the code for different
>> target machines. That's the biggest thing C gives me over assembly, i.e.
>> the
>> ability to write source code once and have it compile to different forms
>> of
>> machine code.
>>
>> For example, I should be able to write a device driver or a memory
>> manager
>> in C and have it run on an x86 whether that machine is running in 16-bit
>> mode, 32-bit mode or 64-bit mode. Therefore I have specific requirements
>> over how wide certain integers are, as follows.

>
> Take a step back here, and think about whether you are doing something
> sensible here. Almost any new x86 system will support 64-bit, though it
> might be used in 32-bit mode. But it's been a decade since 16-bit x86
> was significantly used, even in embedded systems. And for those few
> that still use 16-bit x86 for legacy reasons, they will need to stick to
> their legacy OS (typically FreeDOS). So unless you have some very
> special situation in mind, I think the userbase for a new 16-bit x86 OS
> will be approximately 0.


You know, starting to explain a big project in some detail inevitably leads
to further questions about details not yet explained. In this case the
inclusion of 16-bit mode is very deliberate largely because it is easily
available and significantly different from the other modes. It is its
difference that makes it an attractive target because it helps to improve
the machine-independence of the design. The three x86 modes are conveniently
available as they are present on any PC and in emulators and are thus easy
to test. I am also looking at an Arm variant for the same reason - to ensure
the design maintains a distance from a particular machine. It's not a
perfect approach because even x86 and Arm share common characteristics. But
I don't intend to support real oddities such as machines with 40-bit words.

....

> Call them something like "int_native" and "uint_native". But don't use
> these names directly in the code - use them only for making typedefs for
> typenames that make sense in the real code (like "pid", "handle", or
> whatever). That makes the code clearer, stops users from taking
> dangerous shortcuts (like using "int" instead of "handle"), and makes it
> easier to change things later.


I will do this in some cases but not all. For example, in a list manager I
have it would be madness to duplicate the code for different types of
integer even though they are really all the same.

Further, there are many cases where code wants a plain integer which does
not represent a specific OS component. Consider something as universal as

for (i = start; i < past; i++)

In this, on 64-bit mode, sometimes i could be 32-bit. At other times it
would need to be 64-bit. It all depends on how the index is to be used. So
it does make sense to permit both types and to support them in a way that
would be transparent on machines with smaller registers or address busses.

James


 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-16-2013
"BartC" <(E-Mail Removed)> writes:
[...]
> C makes treats upper and lower case variations of a name distinctly. So you
> could use SINT (or INT or Int) and UINT.


Sure, but I'd say `INT` is a poor name for a type. If it's always the
same as `int`, then it's useless; just use `int`. If it's *not* always
the same as `int`, then the name is misleading.

> I have also used 'word' to mean unsigned, leaving 'int' to mean signed (I
> think 'int' is always signed unless you add 'unsigned').


Yes, `int` synonymous with `signed int` (except that for a bit field,
it's implementation-defined whether `int` means `signed int` or
`unsigned int`).

> With the type that's capped at 32-bits, what is the purpose of that? Perhaps
> they could be given a more relevant name than just an 'int'-based one.
>
> Also, is the 'uint' of that compiler a macro? I thought you could override
> macro names.


It's more likely to be a typedef, and you can't override those. You can
avoid them by not `#include`ing the header that defines them, but it
might be included indirectly or you might need other declarations in the
same header.

No conforming compiler may define the name `uint` by default, since it's
in the user namespace -- but not all compilers are conforming by default.

> Actually I think you can override built-in names too for that
> matter:
>
> #define int int32_t
>
> But use with some care...


I believe macros that redefine keywords cause undefined behavior.
They're certainly dangerous. For example, if `int32_t` is a typedef,
then the above macro definition makes `unsigned int` a syntax error.

Don't do that.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(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
 
 
 
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
reference type for C roland.arthaud@gmail.com C Programming 206 05-28-2013 01:53 AM
Suitable libraries for implementing a "push"-type matching engine? Andrew Warkentin Python 0 04-11-2008 09:23 AM
Portable Python - free portable development environment ! perica.zivkovic@gmail.com Python 7 01-13-2007 11:19 AM
portable (VHDL) vs. non-portable (altera LPM) approaches to signed computations Eli Bendersky VHDL 1 03-01-2006 02:43 PM
XSL rules applying to XSD (XML schema) defined type names (as opposed to node names) Lewis G. Pringle, Jr. XML 0 09-30-2003 10:34 PM



Advertisments