lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


In Lua 5.2, there is a definition for 'l_noret' which is as follows:

#if defined(__GNUC__)
#define l_noret		void __attribute__((noreturn))
#elif defined(_MSC_VER)
#define l_noret		void __declspec(noreturn)
#else
#define l_noret		void
#endif

The macro is used to mark some functions as never returning, typically
because they always throw an error.
GCC and MSVC compilers can use this as an optimizing hint and as a way
to suppress some irrelevant warnings.

My first question is: why don't public API functions also use that attribute ?
Those external functions could be declared as 'noreturn':

LUA_API int   (lua_error) (lua_State *L);
LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);

I may have an answer: maybe it is because they return a dummy 'int' value.
And Microsoft compiler issue a warning when '__declspec(noreturn)' is
used on a function returning something else than 'void'.
Converting those 3 functions to 'l_noret' result in an important
number of changes (see the annexed patch [1]), because in a number of
places there is the idiom : 'return lua_error(L);' or similar. From
some Googling, I noticed that a number of Lua bindings use this idiom
too.

A second question arises: is there any benefit to write 'return
lua_error(L)' instead of just 'lua_error(L)' ? Is this the reason why
lua_error returns an 'int' instead of 'void' ?

[1] A small compilation test show a slight decrease in the executable
size (512 bytes) when the patch is applied.
Not very compelling, but still an argument for such a move in Lua 5.2.1...

Attachment: lua-5.2.0-noret.patch.gz
Description: GNU Zip compressed data