What's the difference between luaL_checknumber and lua_tonumber?
lua
Solution
The reference manual does answer this question. I'm citing the Lua 5.2 Reference Manual, but similar text is found in the 5.1 manual as well. The manual is, however, quite terse. It is rare for any single fact to be restated in more than one sentence. Furthermore, you often need to correlate facts stated in widely separated sections to understand the deeper implications of an API function.
This is not a defect, it is by design. This is the reference manual to the language, and as such its primary goal is to completely (and correctly) describe the language.
For more information about "how" and "why" the general advice is to also read Programming in Lua. The online copy is getting rather long in the tooth as it describes Lua 5.0. The current paper edition describes Lua 5.1, and a new edition describing Lua 5.2 is in process. That said, even the first edition is a good resource, as long as you also pay attention to what has changed in the language since version 5.0.
The reference manual has a fair amount to say about the `luaL_check*` family of functions.
Each API entry's documentation block is accompanied by a token that describes its use of the stack, and under what conditions (if any) it will throw an error. Those tokens are described at section 4.8:
Each function has an indicator like this: `[-o, +p, x]`
The first field, o, is how many elements the function pops from the stack. The second field, p, is how many elements the function pushes onto the stack. (Any function always pushes its results after popping its arguments.) A field in the form x|y means the function can push (or pop) x or y elements, depending on the situation; an interrogation mark '?' means that we cannot know how many elements the function pops/pushes by looking only at its arguments (e.g., they may depend on what is on the stack). The third field, x, tells whether the function may throw errors: '-' means the function never throws any error; 'e' means the function may throw errors; 'v' means the function may throw an error on purpose.
At the head of Chapter 5 which documents the auxiliary library as a whole (all functions in the official API whose names begin with `luaL_` rather than just `lua_`) we find this:
Several functions in the auxiliary library are used to check C function arguments. Because the error message is formatted for arguments (e.g., "bad argument #1"), you should not use these functions for other stack values.
Functions called luaL_check* always throw an error if the check is not satisfied.
The function `luaL_checknumber` is documented with the token `[-0,+0,v]` which means that it does not disturb the stack (it pops nothing and pushes nothing) and that it might deliberately throw an error.
The other functions that have more specific numeric types differ primarily in function signature. All are described similarly to `luaL_checkint()` "Checks whether the function argument `arg` is a number and returns this number cast to an `int`", varying the type named in the cast as appropriate.
The function `lua_tonumber()` is described with the token `[-0,+0,-]` meaning it has no effect on the stack and does not throw any errors. It is documented to return the numeric value from the specified stack index, or 0 if the stack index does not contain something sufficiently numeric. It is documented to use the more general function `lua_tonumberx()` which also provides a flag indicating whether it successfully converted a number or not.
It too has siblings named with more specific numeric types that do all the same conversions but cast their results.
Finally, one can also refer to the source code, with the understanding that the manual is describing the language as it is intended to be, while the source is a particular implementation of that language and might have bugs, or might reveal implementation details that are subject to change in future versions.
The source to `luaL_checknumber()` is in `lauxlib.c`. It can be seen to be implemented in terms of `lua_tonumberx()` and the internal function `tagerror()` which calls `typerror()` which is implemented with `luaL_argerror()` to actually throw the formatted error message.
Problem
Clarification (sorry the question was not specific): They both try to convert the item on the stack to a `lua_Number`. `lua_tonumber` will also convert a string that represents a number. How does `luaL_checknumber` deal with something that's not a number? There's also `luaL_checklong` and `luaL_checkinteger`. Are they the same as `(int)luaL_checknumber` and `(long)luaL_checknumber` respectively?