Why in most os/tutorials primitive data type are redefined?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
finarfin
Member
Member
Posts: 106
Joined: Fri Feb 23, 2007 1:41 am
Location: Italy & Ireland
Contact:

Why in most os/tutorials primitive data type are redefined?

Post by finarfin »

Ok this sounds maybe like a newbie question,

but i always used primitive data type as they were, without redefining them, but now essentially at every tutorial/os source that i look i always see something like:

Code: Select all

typedef unsigned int uint32_t;
typedef unsigned long uint64_t;
//etc...
My question is simply Why?
What are the pros and cons (if there are of using these typedef?) and not doing it is so bad practice, or is still ok?

Is it worth doing it? (i just started my new kernel, it is only few hundred lines of code at the moment, so if i decide to redefine the primitive data time i'm still in time :D)
Elen síla lúmenn' omentielvo
- DreamOS64 - My latest attempt with osdev: https://github.com/dreamos82/Dreamos64
- Osdev Notes - My notes about osdeving! https://github.com/dreamos82/Osdev-Notes
- My old Os Project: https://github.com/dreamos82/DreamOs
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Why in most os/tutorials primitive data type are redefin

Post by iansjack »

A primitive data type, such as "int", in C is not a fixed quantity. Depending upon the compiler it may be 16, 32, or 64 bits. When dealing with items of specific sizes - such as hardware registers, structures describing a file system, etc. - it is imperative that the size of elements is accurately specified. "int" does not do that "uint32_t" does (as long as it is properly defined). This depends upon the redefinition in the headers being crafted for the particular compiler being used, so you will usually see the definition embedded in #ifdef blocks.
Korona
Member
Member
Posts: 1000
Joined: Thu May 17, 2007 1:27 pm
Contact:

Re: Why in most os/tutorials primitive data type are redefin

Post by Korona »

Because the authors do not realize that stdint.h is a freestanding header that should be provided by the compiler even in freestanding mode (and it indeed is, at least if you're using GCC or Clang).

Do not do this, properly set up your cross compiler instead.

Also keep in mind that most tutorials are not written by experts since the experts sadly rarely have time to write intro tutorials.
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Why in most os/tutorials primitive data type are redefin

Post by iansjack »

But be aware that older versions of the Microsoft compiler did not include this header, in which case you might need to define the types yourself. I know a number of people use Windows for OS development.
User avatar
finarfin
Member
Member
Posts: 106
Joined: Fri Feb 23, 2007 1:41 am
Location: Italy & Ireland
Contact:

Re: Why in most os/tutorials primitive data type are redefin

Post by finarfin »

Ok thanks guys, that makes everything clear.

Now i just need to or reimplement them, or recompile gcc without the --without-headers option (this is my understanding).
Elen síla lúmenn' omentielvo
- DreamOS64 - My latest attempt with osdev: https://github.com/dreamos82/Dreamos64
- Osdev Notes - My notes about osdeving! https://github.com/dreamos82/Osdev-Notes
- My old Os Project: https://github.com/dreamos82/DreamOs
Korona
Member
Member
Posts: 1000
Joined: Thu May 17, 2007 1:27 pm
Contact:

Re: Why in most os/tutorials primitive data type are redefin

Post by Korona »

Just not passing -nostdinc should be enough. AFAIK freestanding headers should be available regardless of configure flags. (And a properly set up cross GCC should not search though host dirs even without -nostdinc. So you still need to make sure to set up --with-sysroot and/or --without-headers correctly. If set up correctly, GCC should not try to use libc during build.)
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
User avatar
finarfin
Member
Member
Posts: 106
Joined: Fri Feb 23, 2007 1:41 am
Location: Italy & Ireland
Contact:

Re: Why in most os/tutorials primitive data type are redefin

Post by finarfin »

Ok actually these are my CFLAGS:
-std=gnu99 \
-ffreestanding \
-O2 \
-Wall \
-Wextra \
-I src/include \
-I src/include/kernel
And the sources are compiling fine after including and declaring a uint64_t type variable. I suppose that means that everything is configured correctly, right?
Elen síla lúmenn' omentielvo
- DreamOS64 - My latest attempt with osdev: https://github.com/dreamos82/Dreamos64
- Osdev Notes - My notes about osdeving! https://github.com/dreamos82/Osdev-Notes
- My old Os Project: https://github.com/dreamos82/DreamOs
nullplan
Member
Member
Posts: 1790
Joined: Wed Aug 30, 2017 8:24 am

Re: Why in most os/tutorials primitive data type are redefin

Post by nullplan »

finarfin wrote:My question is simply Why?
What are the pros and cons (if there are of using these typedef?) and not doing it is so bad practice, or is still ok?
It is a bad practice that arose from insufficiencies in early C standards. That is to say, C89 did not have these types. And some people have never grown out of the nineties. To include Microsoft; it took a while for them to include stdint.h.

In practice, you should just not define these types yourself. Just include <stdint.h> and use them. If they are not defined, then that means your particular implementation has no integer type of the requested width. You may get somewhere with the minimum-width types (uint_least32_t etc.)

Defining the types yourself is hard if you don't know what you're doing. You can easily get it wrong. For example, the snippet you quoted happens to work out for CC on Linux on AMD64, but fails for GCC on Linux on i386 as well as GCC on Windows on AMD64. So it is extremely brittle, even minor changes break everything. Whereas if you just use <stdint.h> you always get what you wanted.
finarfin wrote: I suppose that means that everything is configured correctly, right?
Looks about right.
Carpe diem!
Post Reply