Reasonable C types sizes assumption
Reasonable C types sizes assumption
I'm writting my OS for Intel x86-32 processors (actually for 80386). I don't want to play with other processors. So, it is reasonable to do this assumption: char - 8 bits, short - 16 bits, int - 32 bits, long - 32 bits? In 32-bit Windows/Linux all C-compilers (as I know) use these sizes. DOS C-compilers when compiling 32-bit code also use these sizes. In 64-bit Windows/Linux I suppose (I can't check it since I have not 64-bit computer) that I need to mention target arch as i386 and compiler will also use these sizes. Am I right?
P.S: I don't like to use int32_t, uint32_t and others, since I think that they are all needed when your C-program is intended for using on a plenty of different archs. In my OS project I use C as a handy replacement for Intel x86-32 asm and not for making my OS cross-platform. It is my choice.
P.S: I don't like to use int32_t, uint32_t and others, since I think that they are all needed when your C-program is intended for using on a plenty of different archs. In my OS project I use C as a handy replacement for Intel x86-32 asm and not for making my OS cross-platform. It is my choice.
- xenos
- Member
- Posts: 1121
- Joined: Thu Aug 11, 2005 11:00 pm
- Libera.chat IRC: xenos1984
- Location: Tartu, Estonia
- Contact:
Re: Reasonable C types sizes assumption
Even if you target only one architecture, there are certainly lots of compilers for that architecture. If you wish to be independent of the compiler you choose, you should not make any assumptions on the size of types, apart from the C language specification.
The only integer types which have guaranteed fixed sizes are intX_t / uintX_t.
The only integer types which have guaranteed fixed sizes are intX_t / uintX_t.
Re: Reasonable C types sizes assumption
To XenOS: do you know any compiler for Intel x86-32 that uses different sizes? OK, I can imagine one that uses 64-bit long, but "int - 32 bits, short - 16 bit, char - 8 bit" is de-facto standard for Intel x86-32 arch!
Re: Reasonable C types sizes assumption
There are no compilers I know of that deviate from the sizes you've specified.suslik wrote:To XenOS: do you know any compiler for Intel x86-32 that uses different sizes? OK, I can imagine one that uses 64-bit long, but "int - 32 bits, short - 16 bit, char - 8 bit" is de-facto standard for Intel x86-32 arch!
That said, I'm a C compiler engineer. So if I find you, I will shoot you in the head.
Re: Reasonable C types sizes assumption
No. If that happen to your tool-chain it's just luck.suslik wrote:I'm writting my OS for Intel x86-32 processors (actually for 80386). I don't want to play with other processors. So, it is reasonable to do this assumption: char - 8 bits, short - 16 bits, int - 32 bits, long - 32 bits? In 32-bit Windows/Linux all C-compilers (as I know) use these sizes. DOS C-compilers when compiling 32-bit code also use these sizes. In 64-bit Windows/Linux I suppose (I can't check it since I have not 64-bit computer) that I need to mention target arch as i386 and compiler will also use these sizes. Am I right?
Specification are defined not because you like it. And no, even on the same architecture the tool-chain may behave differently due to optimization and all sort of things. One example is that VC may try to optimize a integer into boolean in some situation and alter the size.suslik wrote:P.S: I don't like to use int32_t, uint32_t and others, since I think that they are all needed when your C-program is intended for using on a plenty of different archs.
Yes this is your choice, but I wouldn't call that smart.suslik wrote:It is my choice.
- xenos
- Member
- Posts: 1121
- Joined: Thu Aug 11, 2005 11:00 pm
- Libera.chat IRC: xenos1984
- Location: Tartu, Estonia
- Contact:
Re: Reasonable C types sizes assumption
I can write one that does deviate from these values and it will still be compliant with the C language specification.suslik wrote:To XenOS: do you know any compiler for Intel x86-32 that uses different sizes? OK, I can imagine one that uses 64-bit long, but "int - 32 bits, short - 16 bit, char - 8 bit" is de-facto standard for Intel x86-32 arch!
Re: Reasonable C types sizes assumption
You are too young I remember the time when int used to be 16 bit in pmodeJamesM wrote:There are no compilers I know of that deviate from the sizes you've specified.
That said, I'm a C compiler engineer. So if I find you, I will shoot you in the head.
@suslik: that's no longer true that int represents the native word size, because on x86_64 int is still 32 bit, not 64. Also long should be 64 bit on i386, but some os define it as 32 bit (which is simply silly, as you already have a 32 bit numeric type). The forms uint32_t and uint64_t are unambiguous and definite, compiler independent and easier to write and read.
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: Reasonable C types sizes assumption
"Conventionally", int was the "native operation size" and long was "the same size as a pointer" (where this is kind of "the way things were" rather than defined by any actual standard)
So, for IA-32, int = long = 32 bits was logical; while for AMD64 int=32-bit, long=64-bit is logical (because 32-bit operations are both smaller and faster), And for IA-16? int=short=16-bit, long=32-bit made sense (also long is >=32-bit)
Just use stdint.h, and note the int_fastX_t types also (since they are on some architectures faster)
So, for IA-32, int = long = 32 bits was logical; while for AMD64 int=32-bit, long=64-bit is logical (because 32-bit operations are both smaller and faster), And for IA-16? int=short=16-bit, long=32-bit made sense (also long is >=32-bit)
Just use stdint.h, and note the int_fastX_t types also (since they are on some architectures faster)
Re: Reasonable C types sizes assumption
I am just wondering whether this is so straightforward with x86-64 or not. I do not think that x86-64 is so 64-bit than 80386 is 32-bit.turdus wrote:that's no longer true that int represents the native word size, because on x86_64 int is still 32 bit, not 64
I mean that the 64-bit size appears to be "less" native here because of immediate sizes in opcodes and the need of REX prefix when using 64-bit features. It seems the processor likes to behave like a 32-bit one unless a user deliberately wants it to be 64-bit. Nevertheless, the whole idea of x86-64 is to be an extension to x86.
With that in mind, it would be reasonable to keep 32-bit int. In this case, it is not just for the backward compatibility.
Re: Reasonable C types sizes assumption
- Surely it is good to write code that is conform to ANSI C, but sometimes it is safe to do some assumptions like I did. I just ask the osdev community is my assumption reasonable.Just use stdint.h, and note the int_fastX_t types also (since they are on some architectures faster)
- This compiler will be original but unpractical.I can write one that does deviate from these values and it will still be compliant with the C language specification.
- Sorry, but I don't think so.No. If that happen to your tool-chain it's just luck.
- Interesting, but vaguely.even on the same architecture the tool-chain may behave differently due to optimization and all sort of things. One example is that VC may try to optimize a integer into boolean in some situation and alter the size
Conclusion: While I'm writing my OS I try to make some reasonable assumptions to make its code simplier. Some days ago at this forum I tried to proof that my assumptions about bootloader were reasonable (I think that bootloader code need not detect the CPU is >= 80386, check VGA-mode and print verbose error messages), and I failed to do it.
- Griwes
- Member
- Posts: 374
- Joined: Sat Jul 30, 2011 10:07 am
- Libera.chat IRC: Griwes
- Location: Wrocław/Racibórz, Poland
- Contact:
Re: Reasonable C types sizes assumption
It is not; only (u)intX_t are reasonable.suslik wrote:- Surely it is good to write code that is conform to ANSI C, but sometimes it is safe to do some assumptions like I did. I just ask the osdev community is my assumption reasonable.Just use stdint.h, and note the int_fastX_t types also (since they are on some architectures faster)
Bullshit, apps that don't care won't care, and apps that care about exact variable sizes use (u)intX_t.suslik wrote:- This compiler will be original but unpractical.I can write one that does deviate from these values and it will still be compliant with the C language specification.
C standard, as well as C++ standard, disagree with you.suslik wrote:- Sorry, but I don't think so.No. If that happen to your tool-chain it's just luck.
Surprising optimizations like that can really surprise you and take you hours to debug problem arising from them.suslik wrote:- Interesting, but vaguely.even on the same architecture the tool-chain may behave differently due to optimization and all sort of things. One example is that VC may try to optimize a integer into boolean in some situation and alter the size
"simpler code" = code without assumptions. You need no assumption about size of (u)intX_t - it's always X bits. And, no-one disallows you to disagree with people here; just bear in mind that those people here (and that's definitely not including me) have way greater experience in the field of OS development than you - or I - do.suslik wrote:Conclusion: While I'm writing my OS I try to make some reasonable assumptions to make its code simplier. Some days ago at this forum I tried to proof that my assumptions about bootloader were reasonable (I think that bootloader code need not detect the CPU is >= 80386, check VGA-mode and print verbose error messages), and I failed to do it.
Reaver Project :: Repository :: Ohloh project page
<klange> This is a horror story about what happens when you need a hammer and all you have is the skulls of the damned.
<drake1> as long as the lock is read and modified by atomic operations
<klange> This is a horror story about what happens when you need a hammer and all you have is the skulls of the damned.
<drake1> as long as the lock is read and modified by atomic operations
Re: Reasonable C types sizes assumption
You asked, we commented, you stand your choice, good luck.
Re: Reasonable C types sizes assumption
Hi,
However, it would be not be reasonable to claim that this new language is C. It'd be a fraudulent/misleading claim if there are differences (even if the differences are minor).
Cheers,
Brendan
It might be reasonable to define a new language that is almost exactly the same a C, except for differences in the restrictions the formal specification gives to integer sizes. You could even claim that some existing C compilers support your new "almost identical to C" language.suslik wrote:So, it is reasonable to do this assumption: char - 8 bits, short - 16 bits, int - 32 bits, long - 32 bits? In 32-bit Windows/Linux all C-compilers (as I know) use these sizes.
However, it would be not be reasonable to claim that this new language is C. It'd be a fraudulent/misleading claim if there are differences (even if the differences are minor).
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: Reasonable C types sizes assumption
Depends on what your definition of "reasonable" is. Given that it's very easy to avoid making these assumptions, why wouldn't you?suslik wrote:I'm writting my OS for Intel x86-32 processors (actually for 80386). I don't want to play with other processors. So, it is reasonable to do this assumption: char - 8 bits, short - 16 bits, int - 32 bits, long - 32 bits? In 32-bit Windows/Linux all C-compilers (as I know) use these sizes. DOS C-compilers when compiling 32-bit code also use these sizes. In 64-bit Windows/Linux I suppose (I can't check it since I have not 64-bit computer) that I need to mention target arch as i386 and compiler will also use these sizes. Am I right?
lol. What is the logic behind that statement?suslik wrote:P.S: I don't like to use int32_t, uint32_t and others, since I think that they are all needed when your C-program is intended for using on a plenty of different archs.
The only scalar types, yes.XenOS wrote:The only integer types which have guaranteed fixed sizes are intX_t / uintX_t.
Why is this relevant? No one will do an exhaustive search on all C x86 ABI's, and no one can predict with certainty whether someone will implement a new, incompatible ABI in the future. One of the points of HLL's is independence of the underlying platforms, for portability---you are basically trying write your code such that it is dependent on your platform for no real reason, thus negating that portability for no real reason. So the way I see it, nothing good can come out of it; however, something bad does come out of it: you either restrict yourself to one particular ABI, or decrease maintainability and risk introducing bugs in the case you later change your mind about sticking to one particular ABI (that includes later deciding to also port to a new architecture).suslik wrote:To XenOS: do you know any compiler for Intel x86-32 that uses different sizes? OK, I can imagine one that uses 64-bit long, but "int - 32 bits, short - 16 bit, char - 8 bit" is de-facto standard for Intel x86-32 arch!
That said, in there x86-64 world, there are competing C ABI's that define types differently (see x32 vs. SysV AMD64), even if it's not the types you happened to mention.
You can't write it off to luck---if makes unnecessary assumptions, it's just bad code.bluemoon wrote:No. If that happen to your tool-chain it's just luck.
<pedantic>It's <stdint.h>, not stdint.h, because it needn't be implemented as a file; indeed, C is often implemented on platforms where file systems don't exist.</pedantic> (u)int_leastN_t and (u)int_fastN_t define types that have a minimum width of N bits but they are also optional.Owen wrote:Just use stdint.h, and note the int_fastX_t types also (since they are on some architectures faster)
Those types do not exist in ANSI C (people generally mean C89 when they say that) because that was the only version of the standard that was defined by an ANSI committee. ANSI later adopted ISO C99 and will likely also adopt C11 in the future.suslik wrote:- Surely it is good to write code that is conform to ANSI C, but sometimes it is safe to do some assumptions like I did. I just ask the osdev community is my assumption reasonable.Just use stdint.h, and note the int_fastX_t types also (since they are on some architectures faster)
That said, I postulate that it is never entirely safe to make assumptions. If there's something you cannot afford to cover due to limited resources, then state when you define your requirements. Assumptions is something sloppy programmers fall back to.
It is only made unpractical by your own assumptions.suslik wrote:- This compiler will be original but unpractical.XenOS wrote:I can write one that does deviate from these values and it will still be compliant with the C language specification.
While this is theoretically correct, it's anything but reasonable to define a new language as C with a particular ABI. Not to mention that it would only cause confusion.Brendan wrote:It might be reasonable to define a new language that is almost exactly the same a C, except for differences in the restrictions the formal specification gives to integer sizes.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: Reasonable C types sizes assumption
(u)int_fastN_t and (u)int_leastN_t are mandatory. uintN_t is mandatory only if the implementation provides an unsigned type of exactly N bits, and intN_t only if the implementation provides a 2s complement signed type of exactly N bits; while the fastN and leastN types are always requiredLove4Boobies wrote:<pedantic>It's <stdint.h>, not stdint.h, because it needn't be implemented as a file; indeed, C is often implemented on platforms where file systems don't exist.</pedantic> (u)int_leastN_t and (u)int_fastN_t define types that have a minimum width of N bits but they are also optional.Owen wrote:Just use stdint.h, and note the int_fastX_t types also (since they are on some architectures faster)
ANSI adopted C11 when ISO did. ANSI C *is* C89; the first ISO C standard was C90.Love4Boobies wrote:Those types do not exist in ANSI C (people generally mean C89 when they say that) because that was the only version of the standard that was defined by an ANSI committee. ANSI later adopted ISO C99 and will likely also adopt C11 in the future.suslik wrote:- Surely it is good to write code that is conform to ANSI C, but sometimes it is safe to do some assumptions like I did. I just ask the osdev community is my assumption reasonable.Just use stdint.h, and note the int_fastX_t types also (since they are on some architectures faster)