logoalt Hacker News

Consequences of passing too few register parameters to a C function

70 pointsby aragonitelast Tuesday at 2:55 AM25 commentsview on HN

Comments

bananamogultoday at 1:54 AM

Raymend Chen has probably forgotten more about programming than I'll ever know, but aren't the first two blah() function examples either missing a } or have a superfluous { after the else?

show 2 replies
CodeArtisantoday at 4:11 AM

Until C23, you could declare a pointer to a procedure that takes an unspecified amount of any type arguments like this

    void foo( int (*f)() )
    {
        f(1);
        f(1, "2" , 3.0);
    }
https://godbolt.org/z/s6e5rnqv9

If you compile with -std=c23, both gcc and clang will throw an error ( (*f)() is now the same as (*f)(void) )

show 1 reply
anitiltoday at 1:46 AM

I had never considered the idea of passing too few register params so I didn't immediately think of the reuse problem. And I had no idea about Itanium's Not-a-thing bit! Always a good read from Raymond Chen.

charleslmungertoday at 3:38 AM

I had fun exploiting this to detect the falling convention used by some code at runtime - there were two different options depending on OS version; one passed a jnienv* as the first param, the other did not. So if I called it with 0, I could tell which was being used based on whether the first argument was NULL or not. Only used for specific architectures with a defined ABI that behaved this way, of course.

hyperhellotoday at 3:05 AM

Do you really not ‘pass’ register parameters? How can anyone tell if you didn’t?

show 1 reply
LelouBiltoday at 3:29 AM

Interesting that some CPUs have a calling convention "built-in"

9fwfj9rtoday at 3:24 AM

I regard this yet another unintuitive Itanium quirk that makes it failed.

marlburrowtoday at 4:02 AM

[flagged]

rurbantoday at 3:27 AM

Of which decade is this post? I cannot think of any modern architecture which still passes args on the stack.

Itanium? Stone age

show 1 reply
_kst_today at 3:15 AM

It's not even possible to pass too few arguments to a function in C unless you go out of your way to write bad code.

You can write a function declaration that's inconsistent with its definition in another translation unit. Declaring the function in a shared header file avoids this.

You can use an old-style declaration that doesn't specify what parameters a function expects. Don't do that. Use prototypes.

You can use a cast to convert a function pointer to an incompatible type, and call through the resulting pointer. Don't do that.

You can call a function with no visible declaration if your compiler overly permissive or is operating in pre-C99 mode. Don't do that.

show 2 replies