Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
tree: Declare empty argument lists
Declare functions w/o arguments explicitly to satisfy my personal
aesthetics.

A function declaration `void foo()` has as unspecified argument list
while a function declared as `void foo(void)` has explicitly no
arguments.

On x86_64 this makes a slight difference on how this functions needs to
be called. Because a function with an unspecified argument list might be
a variadic function, the ABI requires that the caller sets %al to the
number of floating point registers which might have been used to pass
in floating point parameters:

"For calls that may call functions that use varargs or stdargs
(prototype-less calls or calls to functions containing ellipsis (...) in
the declaration) %al is used as hidden argument to specify the number of
vector registers used. The contents of %al do not need to match exactly
the number of registers, but must be an upper bound on the number of
vector registers used and is in the range 0–8 inclusive" [1]

If the callee is a variadic function, the usual routine in the function
prologue is to save the registers, which might have been used to pass
parameters, to memory so that they can be access one-by-one in the
function body via pointers or indices. To give the callee an uppper bound
of the number of floating point registers used to pass parameters opens
an opportunity to avoid saving unused registers.

The call of foo in

    void foo();
    void bar(void) {
        foo();
    }

might compile to something like

    movl $0, %eax
    call foo

The `movl $0, %eax` instruction would not be needed if foo was defined
as `void foo(void)`.

Note 1: gcc avoids the unneeded instructions to set up %al with -O1 or
higher O1` if the function is known to be non-variadic because it is
defined in the compilation uniti where it is used.

Note 2: gcc function prologue for variadic functions just checks whether
%al is zero or not and either saves none or all 8 floating point
registers potentially used for arguments.

Note 3: An instruction to clear %al (e.g. `31 c0 :  xor %eax, %eax`)
might have zero runtime cost on a modern processors. This change here is
not a relevant optimization. I said, this is more about aesthetics.

[1]: https://refspecs.linuxfoundation.org/elf/x86_64-abi-0.99.pdf
  • Loading branch information
donald committed Feb 28, 2022
1 parent 074977d commit 5b7e60b
Show file tree
Hide file tree
Showing 7 changed files with 10 additions and 10 deletions.
2 changes: 1 addition & 1 deletion mx_util.c
Expand Up @@ -1306,7 +1306,7 @@ unsigned long mx_df(const char *path) {
return s.f_bavail*s.f_frsize;
}

time_t mx_clock_boottime() {
time_t mx_clock_boottime(void) {
struct timespec ts;
int res = clock_gettime(CLOCK_BOOTTIME, &ts);
if (res != 0) {
Expand Down
2 changes: 1 addition & 1 deletion mx_util.h
Expand Up @@ -179,7 +179,7 @@ void _mx_sort_linked_list(void **list, int (*cmp)(void *o1,void *o2), void ** (*
#define mx_sort_linked_list(list,cmp,getnextptr) _mx_sort_linked_list((void **)(list),(int (*)(void *,void *))(cmp),(void ** (*)(void *))(getnextptr))

unsigned long mx_df(const char *path);
time_t mx_clock_boottime();
time_t mx_clock_boottime(void);
char *mx_call_external(char *args, ...);

#endif
2 changes: 1 addition & 1 deletion mxqd.c
Expand Up @@ -334,7 +334,7 @@ static void read_hostconfig_retry(struct keywordset *kws) {

static char gpu_setup_script[] = LIBEXECDIR "/mxq/gpu-setup";

static int get_gpus() {
static int get_gpus(void) {
char *line = mx_call_external(gpu_setup_script, "init", NULL);
if (!line) {
mx_log_err("gpu-setup init: %m");
Expand Down
2 changes: 1 addition & 1 deletion ppidcache.c
Expand Up @@ -16,7 +16,7 @@ struct ppidcache {
struct entry *entries;
};

struct ppidcache *ppidcache_new() {
struct ppidcache *ppidcache_new(void) {
struct ppidcache *ppidcache = mx_malloc_forever(sizeof(struct ppidcache));
ppidcache->count = 0;
ppidcache->alloc = 500;
Expand Down
2 changes: 1 addition & 1 deletion ppidcache.h
Expand Up @@ -3,7 +3,7 @@

#include <sys/types.h>

struct ppidcache *ppidcache_new();
struct ppidcache *ppidcache_new(void);
void ppidcache_free (struct ppidcache *ppidcache);
pid_t ppidcache_get_ppid(struct ppidcache *ppidcache, pid_t pid);
int ppidcache_is_descendant(struct ppidcache *ppidcache, pid_t ancestor, pid_t candidate);
Expand Down
8 changes: 4 additions & 4 deletions test_mx_util.c
Expand Up @@ -347,7 +347,7 @@ static void test_mx_strscan(void)
mx_proc_pid_stat_free_content(pps);
}

static void test_mx_strvec() {
static void test_mx_strvec(void) {
char **strvec;
char *str;

Expand Down Expand Up @@ -395,7 +395,7 @@ static void test_mx_strvec() {
free(strvec);
}

static void test_mx_strcat() {
static void test_mx_strcat(void) {
char *str;
char *str2;

Expand Down Expand Up @@ -517,11 +517,11 @@ static void test_listsort(void)
assert(o[9].next==NULL);
}

static void test_mx_df() {
static void test_mx_df(void) {
assert(mx_df("/") > 0);
}

static void test_mx_call_external() {
static void test_mx_call_external(void) {
char *line;

errno = 999;
Expand Down
2 changes: 1 addition & 1 deletion xmalloc.h
Expand Up @@ -4,7 +4,7 @@
#include <stdio.h>
#include <stdlib.h>

__attribute__ ((noreturn, unused)) static void out_of_memory() {
__attribute__ ((noreturn, unused)) static void out_of_memory(void) {
fprintf(stderr,"out of memory\n");
abort();
}
Expand Down

0 comments on commit 5b7e60b

Please sign in to comment.