10
void
usage (cpp)
    register const char *const *cpp;
{
    (void) fprintf (stderr, *cpp++, program_name, cvs_cmd_name);
    for (; *cpp; cpp++)
    (void) fprintf (stderr, *cpp);
    error_exit ();
}

I don't get why register variable is not inside the curly brackets and what is this (void) in front of fprintf? Also register const char *const *cpp, i've never seen anything like this before

P.P
  • 117,907
  • 20
  • 175
  • 238
woowoo
  • 117
  • 1
  • 6
  • The `(void)` in front of fprintf is just used to make it explicit that the return value is not being used. – 0RR Dec 31 '20 at 21:26

2 Answers2

13

The reason you've "never seen this before" is because this is using the syntax of the original, historical, K&R C version. That must be some real, old C code you're looking at. I just looked up, and ANSI C (C90) came out in 1990, so this code must be at least 30 years, or so, old.

I suppose this is something that needs to be known if one needs to deal with historic C code, but otherwise you can simply forget it.

The (void) cast means the same thing it means today.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • so we don't use that syntax anymore in c? – woowoo Dec 31 '20 at 21:32
  • Because this syntax is more error-prone. C90+ syntax forces the type of every parameter to be explicitly specified. Here, you can forget accidentally, and end up with an `int` parameter. If this doesn't make the resulting code ill-formed, you'll have a Scooby-Doo mystery to figure out -- why the resulting code crashes. – Sam Varshavchik Dec 31 '20 at 21:34
  • 4
    While the arg syntax is K&R, K&R didn't have `void` or `const`. – Craig Estey Dec 31 '20 at 21:34
6

The register keyword is a hint to the compiler that you'd like that value to be kept in a dedicated register on the processor. This can speed up reads and writes. With modern compilers, however, this sort of optimization is not only unnecessary but often counterproductive.

The reason it is between the function declaration and the block is that in old c (pre C90) you wouldn't declare parameter type next to the parameter but between the declaration of the function and the block.

For example:

int main(argc, argv)
char ** argv;
{
 ...
}

Notice I didn't do anything for argc because if you don't explicitly define a type it defaults to int.

You'll see this more often than you'd think. I ran into this a bunch when I did work on FFMPEG.

The (void) cast thing prevents unused parameter warnings/errors. I've run into this when working on PortAudio with a low-level callback function.

Jacob Blomquist
  • 276
  • 1
  • 5