Size of function arguments

Programming, for all ages and all languages.
User avatar
BMW
Member
Member
Posts: 286
Joined: Mon Nov 05, 2012 8:31 pm
Location: New Zealand

Size of function arguments

Post by BMW »

Is it a good idea to make arguments of a function 32 bits even if it only needs an 8-bit number? Because it will still take the same amount of space on the stack, and the CPU has to waste time padding the argument with zeros if you use a 1-byte argument as opposed to a 4-byte argument.

Or would the compiler do this for you anyway?

BTW I am talking about an OS running in 32-bit mode.
Currently developing Lithium OS (LiOS).

Recursive paging saves lives.
"I want to change the world, but they won't give me the source code."
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Size of function arguments

Post by Combuster »

Well, the only thing you end up doing is lying to the compiler about the actual types of your arguments, which makes it harder for you to diagnose bugs. You're not going to save on instruction counts.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
iansjack
Member
Member
Posts: 4706
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Size of function arguments

Post by iansjack »

Why would the compiler have to waste time padding the argument? It can just use the 8-bit push immediate instruction or the movsx instruction if not an immediate value.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: Size of function arguments

Post by AJ »

HI,

In addition to the above responses, if you use the correct types as function arguments then you leave the compiler free to optimise where possible.

Cheers,
Adam
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Size of function arguments

Post by Gigasoft »

Unused locations between the parameters are undefined and not required to be zero. Therefore, no zero extension is needed.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Size of function arguments

Post by bluemoon »

BMW wrote:Is it a good idea to make arguments of a function 32 bits even if it only needs an 8-bit number?
Declare your variable with standard int type unless it is required to be an exact N-bit number, on these case use fixed-width integers, and pass it to function without lying (casting).
Mikemk
Member
Member
Posts: 409
Joined: Sat Oct 22, 2011 12:27 pm

Re: Size of function arguments

Post by Mikemk »

bluemoon wrote:Declare your variable with standard int type unless it is required to be an exact N-bit number.
This is such bad advise, I don't even know where to start. [-X

The exact length fields are their in order to ensure an exact length (duh), increasing portability to other platforms (not so duh). If a program uses different field sizes on different platforms, then there are quite a few more bugs to fix when porting to a new platform.
Besides, it's just general good practice to use clear code rather than vague trash.

Code: Select all

#include <stdint.h>
int32_t pagemap
is far clearer than

Code: Select all

#include <limits.h>
#if INT_MAX==2147483647
int pagemap
#elif LONG_MAX==2147483647
long pagemap
#else
long long pagemap // let's hope this is four bytes!
#endif
BMW wrote:Is it a good idea to make arguments of a function 32 bits even if it only needs an 8-bit number? Because it will still take the same amount of space on the stack, and the CPU has to waste time padding the argument with zeros if you use a 1-byte argument as opposed to a 4-byte argument.
CPU performance wise, yes. It's also easier to interface with assembly. However, it uses more ram, and as others have said, results in less optimized code.
Or would the compiler do this for you anyway?
It depends on the compiler. I believe gcc does (correct me if I'm wrong), other compilers might not.
BTW I am talking about an OS running in 32-bit mode.
I would hope so.
Programming is 80% Math, 20% Grammar, and 10% Creativity <--- Do not make fun of my joke!
If you're new, check this out.
FallenAvatar
Member
Member
Posts: 283
Joined: Mon Jan 03, 2011 6:58 pm

Re: Size of function arguments

Post by FallenAvatar »

m12 wrote:...
please read what others have said before you reply. However in response to your "answer", just no. Flat out wrong in so many ways. Please learn what you are talking about before you lead others astray.
m12 wrote:
bluemoon wrote: BTW I am talking about an OS running in 32-bit mode.
I would hope so.
And why would you hope that? 32-bit is very VERY old news at this point, not necessarily for hobbyist OS Dev, but why would you hope so? That's yet another misleading comment...

- Monk
Mikemk
Member
Member
Posts: 409
Joined: Sat Oct 22, 2011 12:27 pm

Re: Size of function arguments

Post by Mikemk »

tjmonk15 wrote:
m12 wrote:
bluemoon wrote: BTW I am talking about an OS running in 32-bit mode.
I would hope so.
And why would you hope that? 32-bit is very VERY old news at this point, not necessarily for hobbyist OS Dev, but why would you hope so? That's yet another misleading comment...
The OP is about padding arguments to 32 bits to save processor time padding them to 32 bits. I would hope that this is being done on a 32-bit processor, otherwise it's somewhat pointless.
Programming is 80% Math, 20% Grammar, and 10% Creativity <--- Do not make fun of my joke!
If you're new, check this out.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Size of function arguments

Post by bluemoon »

m12 wrote:
bluemoon wrote:Declare your variable with standard int type unless it is required to be an exact N-bit number.
This is such bad advise, I don't even know where to start. [-X
For example, a function that take a counter N as parameter and print N *, you would do

Code: Select all

int print_star(int count);
Now if you make a design choice that impose artificial limitation like count < 256, and do this:

Code: Select all

int print_star(uint8_t count);
Let's see the consequence:
When calling print_star with:

Code: Select all

print_star(num);
1. num must be the type of uint8_t, or you'll get conversion warning
2. the compiler may generate 8-bit instruction(if available in architecture), but this wouldn't save instruction count. Also, 8 bit instruction would not run faster than 32-bit instruction.
3. the compiler push full 32-bit on stack anyway
4. it get worst when the type is uint16_t

In the above case, it's just easier to maintain, and out-weight any optimization gain (if any):

Code: Select all

int print_star(int count) {
  if ( count >= 256 ) return -1;
  ...
}
So, if you don't care the parameter width, just use the native integer.
You normally would care the width only on a serializer.
User avatar
Griwes
Member
Member
Posts: 374
Joined: Sat Jul 30, 2011 10:07 am
Libera.chat IRC: Griwes
Location: Wrocław/Racibórz, Poland
Contact:

Re: Size of function arguments

Post by Griwes »

m12 wrote:
bluemoon wrote:Declare your variable with standard int type unless it is required to be an exact N-bit number.
This is such bad advise, I don't even know where to start. [-X
D'oh.
The exact length fields are their in order to ensure an exact length (duh), increasing portability to other platforms (not so duh).
D'oh.

`uintXX_t` and `intXX_t` are not portable. Go grep the C and C++ standards for them, they are optional - they obviously will be available on all sane platforms (using 8 bit bytes), but they are still less portable than anything else.
If a program uses different field sizes on different platforms, then there are quite a few more bugs to fix when porting to a new platform.
If you have serious bugs related to integer size (and I do mean serious), then your code is broken. Every type has defined the required range; you generally just use the one that fits (well, I personally do not follow this one, but since I am not expecting my code to be executed on 7 or 9 or 10 or whatever-bit machines, I am fine with lack of portability).
Besides, it's just general good practice to use clear code rather than vague trash.

Code: Select all

#include <stdint.h>
int32_t pagemap
is far clearer than

Code: Select all

#include <limits.h>
#if INT_MAX==2147483647
int pagemap
#elif LONG_MAX==2147483647
long pagemap
#else
long long pagemap // let's hope this is four bytes!
#endif
WTF is this shite. This is hardware dependent piece of variable, which must be 32 bit long, so you use uint32_t. Seems you've mistaken "not overuse fixed width integers" with "never use fixed width integers", which is just plain retarded.

I think bluemoon already addressed the rest of bullshit in that post.
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
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: Size of function arguments

Post by sortie »

Griwes wrote:
m12 wrote:
bluemoon wrote:Declare your variable with standard int type unless it is required to be an exact N-bit number.
This is such bad advise, I don't even know where to start. [-X
D'oh.
The exact length fields are their in order to ensure an exact length (duh), increasing portability to other platforms (not so duh).
D'oh.

`uintXX_t` and `intXX_t` are not portable. Go grep the C and C++ standards for them, they are optional - they obviously will be available on all sane platforms (using 8 bit bytes), but they are still less portable than anything else.
Don't worry about portability to other platforms when doing operating systems development. You are writing that other platform! If you demand the compiler provide stdint.h, then you are in your right to make that part of your system API. (Unless you want to want parts of your OS on another OS, but that's kinda a special case regardless.)

You guys are likely micro-optimizing. I recommend looking at the function and its domain and then selecting suitable data types from that. For instance, a function that accepts a buffer should get a pointer and a size_t, unless there is any built-in limits in what the function does that means an unsigned int or a signed int will do. There is only no reason to artificially limit the domain of the function (the input must not be higher than some value) unless it would main the function much easier to write and maintain.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Size of function arguments

Post by bluemoon »

sortie wrote:Don't worry about portability to other platforms when doing operating systems development. You are writing that other platform!
You realized many of us targeting multi-platform (e.g. i386 and x86_64, or even ARM)?
If coded carefully, 90%+ code-base of a kernel is platform/architecture independent.

While writing portability code is not a requirement (in case you decided to lock yourself onto one specific platform), it however make your code look more elegant.
User avatar
Griwes
Member
Member
Posts: 374
Joined: Sat Jul 30, 2011 10:07 am
Libera.chat IRC: Griwes
Location: Wrocław/Racibórz, Poland
Contact:

Re: Size of function arguments

Post by Griwes »

sortie wrote:Don't worry about portability to other platforms when doing operating systems development. You are writing that other platform! If you demand the compiler provide stdint.h, then you are in your right to make that part of your system API. (Unless you want to want parts of your OS on another OS, but that's kinda a special case regardless.)
1) This was posted in general programming, assume this is a general thread.
2) stdint.h is required since C99, cstdint is required since C++11; I call every environment not providing either of them utterly broken and outdated.
3) As I said, (u)intXX_t is *not* portable, not because stdint may not exist, but because it is optional.
You guys are likely micro-optimizing. I recommend looking at the function and its domain and then selecting suitable data types from that. For instance, a function that accepts a buffer should get a pointer and a size_t, unless there is any built-in limits in what the function does that means an unsigned int or a signed int will do. There is only no reason to artificially limit the domain of the function (the input must not be higher than some value) unless it would main the function much easier to write and maintain.
Not agreed. Always choose whichever type fits semantically. If the value will never be higher than 255, just use uint8_t - you know, that's why C++ uses sane data type for characters - char - and why C's "'a' is an int!" is broken.

Those differences will be most probably optimized out anyway.
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
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: Size of function arguments

Post by sortie »

bluemoon wrote:
sortie wrote:Don't worry about portability to other platforms when doing operating systems development. You are writing that other platform!
You realized many of us targeting multi-platform (e.g. i386 and x86_64, or even ARM)?
If coded carefully, 90%+ code-base of a kernel is platform/architecture independent.

While writing portability code is not a requirement (in case you decided to lock yourself onto one specific platform), it however make your code look more elegant.
I'm sorry, I shouldn't post in the forums before breakfast. My point is that you get to choose the API and ABI when you write an operating system. For that reason it's useless to think too much about "What if <stdfoo.h> isn't available?" or "What if the compiler doesn't support feature X?" or "What if the calling conventions are totally weird and complicated?" - because you get to choose the answer to those questions by defining the API and ABI. You should figure out what you want in your programming environment and embrace that, rather than worrying that if you port your 'ls' program to NetBSD for <whatever-weird-cpu> from 1997, then it won't work because of <silly-reason>. It's important to be architecture-independent for maintenance reasons, but it's perfectly good to build in assumptions in your OS if you do this as a conscious decision. The same thing applies to programs where it is okay to be non-portable if it eases maintenance and the non-portable assumptions in the program isn't too bad.
Griwes wrote:Not agreed. Always choose whichever type fits semantically. If the value will never be higher than 255, just use uint8_t - you know, that's why C++ uses sane data type for characters - char - and why C's "'a' is an int!" is broken.

Those differences will be most probably optimized out anyway.
Exactly my point, we agree. :-) I must've poorly phrased the part you responded to.
Griwes wrote:This was posted in general programming, assume this is a general thread.
Whoops, I missed that. Sorry.
Post Reply