Page 1 of 1

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

Posted: Wed Mar 03, 2021 3:59 am
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)

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

Posted: Wed Mar 03, 2021 4:08 am
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.

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

Posted: Wed Mar 03, 2021 4:28 am
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.

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

Posted: Wed Mar 03, 2021 4:41 am
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.

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

Posted: Wed Mar 03, 2021 4:58 am
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).

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

Posted: Wed Mar 03, 2021 5:37 am
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.)

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

Posted: Wed Mar 03, 2021 6:17 am
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?

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

Posted: Wed Mar 03, 2021 11:08 am
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.