The Linux manual page for bsearch shows a synopsis beginning with `void *bsearch(size_t n, size_t size; const void key[size], const void base[size * n], size_t n, size_t size, ...);`. It looks as though `n` and `size` appear twice, with the first pair in the wrong place. My locally installed manual page shows the same thing. Is this a documentation error, or is there a C language rule behind this unusual declaration?
3 Answers
It isn't an ordinary C prototype. The semicolon after `size` uses a compiler extension that lets parameters be declared ahead of the point where they're used in later array bounds. That allows the synopsis to describe the intended relationships between the arguments, even though it doesn't look like normal compilable C. The `const void key[size]` notation is also documentation-oriented—there is no actual array of `void`. Manual-page synopses sometimes use language extensions or notation that explains how an interface is used rather than reproducing its exact declaration.
The unusual syntax comes from the way variable-length array parameters can be documented: a length can be introduced before the array parameter that uses it, then the actual argument order is shown afterward. The semicolon is significant; without it, the later `size` names would not have been declared when they were used.
Manual pages can occasionally contain mistakes or become out of date, but this particular case is intentional. `bsearch` is a long-established library function, so its argument order has not suddenly changed. Different operating systems and library versions may also ship somewhat different wording or synopsis formatting, so the locally installed documentation is usually the best reference for the implementation you're using.

That explains why it looks so strange. The synopsis is describing the interface and the sizes involved, not necessarily presenting a declaration that can be copied directly into a C source file.