Use of C89 vs C99

189 views
Skip to first unread message

Roger Leigh

unread,
Aug 30, 2025, 4:34:08 AM (8 days ago) Aug 30
to lu...@googlegroups.com
Hi,


This has likely been discussed previously, but I would like to ask why
the project is using C89 as a baseline, which is now rather long in the
tooth; even C99 is 27 years old at this point (I've been using it for
over 25 years since GCC first added support for it).  Even in the
embedded world, which is notoriously slow to adopt new things, C99 has
been de rigour for well over a decade, if not longer.

The reason for bringing it up is that I've repeatedly run into problems
with the codebase when cross-compiling, usually for 32-bit ARMv7 or v8,
but there are also a host of papercuts when using Lua on regular systems
as well.

* luaconf.h goes through a very complex amount of preprocessor logic to
determine type sizes, format strings etc.  But the assumptions it makes
don't hold for all compilers and platforms and this can be subtly or
unsubtly wrong, leading to bad behaviour at runtime.  Simply using the
C99 <stdint.h> sized types and <inttypes.h> format string macros would
result in guaranteed correct behaviour all of the time, and greatly
simplify things.

* lmathlib.c goes through some very complex contortions with LUA_RAND32,
Rand64/SRand64 and the 32-bit fallback l_uint32, which again could be
entirely removed and replaced with standard sized types from <stdint.h>,
i.e. uint64_t/int64_t with uint32_t as the fallback (if it's needed).

* Similarly there are C89 specialisations for a number of things which
are standard in C99.

Back in 2023 I developed a patchset for my own use which removed all C89
compatibility code and made C99 the baseline, including:

Use C99 integer types and format strings
Use C99 snprintf directly in luaconf.h
Replace all uses of l_sprintf with snprintf
Replace all uses of lua_strx2number with lua_str2number
Replace all uses of lua_number2strx with snprintf
Replace all uses of lua_pointer2str with snprintf
Remove C89 specialisation of l_mathop macro
Remove C89 specialisation of lua_str2number macro
Remove C89 specialisation of L_P2I macro
Unconditionally enable C99 specialisation of LUA_KCONTEXT macro
Remove C89 specialisation of l_inline macro
Remove existing uses of l_inline macro
Unconditionally enable C99 log2 support in math_log
Remove C89 specialisation of LUA_STRFTIMEOPTIONS macro
Update LUA_STRFTIMEOPTIONS for latest Windows options
Remove LUA_USE_C89 option
loslib: Correct strftime options on Windows

If there would be any interest in bringing any or all of these changes
into the Lua codebase, I would be happy to rebase these against the
5.5.0-beta release and submit them.

Note that the Windows strftime options used in Lua are outdated, and
current Windows supports most of the POSIX behaviour, which is why you
see this in the above changelist.


Kind regards,

Roger



Roger Leigh

unread,
Aug 30, 2025, 9:54:49 AM (8 days ago) Aug 30
to lu...@googlegroups.com
On 30/08/2025 09:34, Roger Leigh wrote:

[...]
>
> Back in 2023 I developed a patchset for my own use which removed all
> C89 compatibility code and made C99 the baseline...
[...]
>
> If there would be any interest in bringing any or all of these changes
> into the Lua codebase, I would be happy to rebase these against the
> 5.5.0-beta release and submit them.
>
I updated them in the interim for my own use in any case, you can find
the broken out patchset attached to this email or via git at:

https://gitlab.com/codelibre/lua/lua-releases/-/commits/5.5.0-beta-upstream-c99-baseline?ref_type=heads

(against the 5.5.0-beta release)

or

https://gitlab.com/codelibre/lua/lua-cmake/-/commits/5.5.0-c99-baseline?ref_type=heads

(CMake build).  Used to check all changes are passing the testsuite on
Linux (Alpine, Ubuntu), FreeBSD and Windows.
https://gitlab.com/codelibre/lua/lua-cmake/-/pipelines/2013012672/builds


Now that Windows has gained decent C99 support with recent versions of
Visual C++, and includes snprintf, stdint, inttypes etc., it no longer
needs to build in C89 mode.


This removes a good bit of unnecessary incidental complexity from the
codebase which is almost certainly not required in the present day. 
Hope this is potentially useful for people.


Kind regards,

Roger
0001-lmathlib-Rand64-SRand64-use-stdint.h-types.patch
0010-Remove-C89-specialisation-of-L_P2I-macro.patch
0011-Unconditionally-enable-C99-specialisation-of-LUA_KCO.patch
0012-Remove-C89-specialisation-of-l_inline-macro.patch
0013-l_sinline-macro-is-static-inline.patch
0014-Unconditionally-enable-C99-log2-support-in-math_log.patch
0015-Remove-C89-specialisation-of-LUA_STRFTIMEOPTIONS-mac.patch
0016-Update-LUA_STRFTIMEOPTIONS-for-latest-Windows-option.patch
0017-lprefix-Remove-C89-check.patch
0018-Remove-C89-POSIX-conflict-check.patch
0019-Remove-C89-support.patch
0002-Use-C99-integer-types-and-format-strings.patch
0020-Remove-C89-from-manual.patch
0003-Align-integer-format-strings-with-PRI-macro-usage.patch
0004-LUA_NUMBER_FMT-macros-match-LUA_INTEGER_FMT-and-PRI-.patch
0005-Use-C99-snprintf-directly-in-luaconf.h.patch
0006-Replace-all-uses-of-lua_strx2number-with-lua_str2num.patch
0007-Replace-all-uses-of-lua_number2strx-with-l_sprintf.patch
0008-Replace-all-uses-of-lua_pointer2str-with-l_sprintf.patch
0009-Remove-C89-specialisations-of-l_mathop-and-lua_str2n.patch

Roberto Ierusalimschy

unread,
Aug 30, 2025, 2:17:59 PM (8 days ago) Aug 30
to lu...@googlegroups.com
> This has likely been discussed previously, but I would like to ask why the
> project is using C89 as a baseline, which is now rather long in the tooth;
> even C99 is 27 years old at this point (I've been using it for over 25
> years since GCC first added support for it).  Even in the embedded world,
> which is notoriously slow to adopt new things, C99 has been de rigour for
> well over a decade, if not longer.

Among others, Microsoft Visual Studio C in not fully compatible
with C99. But it would be helpful to hear what others have to say.
I fully agree that removing support for C89 would simplify the code
in lots of places.

-- Roberto

Родион Горковенко

unread,
Aug 30, 2025, 3:03:30 PM (8 days ago) Aug 30
to lu...@googlegroups.com
In perspective, probably, C89 support isn't going to last forever.

Hence it is going to happen anyway. Now or 5, or 10 years later? 

Perhaps it may be good to do it in two stages, say, intentionally 
break C89 compatibility in some chosen single place in v5.5.1 and if no
objections come in a year, finalize the move in v5.5.3 or so.

> Microsoft Visual Studio C in not fully compatible
with C99

But is there an option to make code compatible with both MSVC and C99,
despite they are not fully compatible?

sincerely yours,
Rodion

--
You received this message because you are subscribed to the Google Groups "lua-l" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lua-l+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/lua-l/20250830181751.GA1044261%40arraial.inf.puc-rio.br.

Roberto Ierusalimschy

unread,
Aug 30, 2025, 3:10:45 PM (8 days ago) Aug 30
to lu...@googlegroups.com

Andrey Dobrovolsky

unread,
Aug 30, 2025, 3:21:17 PM (8 days ago) Aug 30
to lu...@googlegroups.com
Some thoughts Imho:

1. The bunch of patches by Roger Leigh are great. I'm sure that
Windows users will appreciate them.
2. Lua's C89 compatibility is exciting.
3. Breaking C89 compatibility doesn't add anything new to Lua.
4. It's absolutely cool when someone has the freedom to choose the
compiler to use. I like tcc. Someone may prefer cproc. Another one may
even write his own compiler.
5. In the current state we have C89 compatible Lua sources and a bunch
of great patches to make the sources C99 compatible. What is to be
changed? I can propose promoting the patches more ,maybe at lua.org

Regards,
Andrew

сб, 30 серп. 2025 р. о 22:03 Родион Горковенко <rodio...@gmail.com> пише:
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/CAL2n1twMcaVKu3y8sUHD9mGVv4YRLu1ShDUUA4K1dkRhgiAObg%40mail.gmail.com.

Andrey Dobrovolsky

unread,
Aug 30, 2025, 3:24:32 PM (8 days ago) Aug 30
to lu...@googlegroups.com
> In perspective, probably, C89 support isn't going to last forever.

Not clear for what reason.

Regards,
Andrew

сб, 30 серп. 2025 р. о 22:20 Andrey Dobrovolsky
<andrey.dobro...@gmail.com> пише:

Luau Project

unread,
Aug 30, 2025, 4:06:04 PM (8 days ago) Aug 30
to lua-l

> But it would be helpful to hear what others have to say.
> I fully agree that removing support for C89 would simplify the code
> in lots of places.

I would vote to drop C89 support and advance the baseline to C99. I can't see a clear gain to stay on C89, which I imagine a small share of Lua users strictly bound to it. Honestly, apart from Lua, I don't know many relevant projects targeting C89 conformance nowadays.

Opposed to others ( http://lua-users.org/lists/lua-l/2022-11/msg00028.html ), the Lua language is not a "single product" killing C89 support, because Lua versions up to 5.4 are going to stay available in the website.

Andrew Trevorrow

unread,
Aug 30, 2025, 7:00:01 PM (8 days ago) Aug 30
to lu...@googlegroups.com
Roberto:

> But it would be helpful to hear what others have to say.

I vote for moving to C99. If it's too late to do that for the 5.5 release
then make that the final version to support C89 and move to C99
in Lua 6.0 and onwards.

Andrew

Jason Lethbridge

unread,
Aug 30, 2025, 8:31:23 PM (8 days ago) Aug 30
to lu...@googlegroups.com
I agree, especially the part about compiler choice.

I'm not against C99 per se but when it comes to old and/or niche
systems you're more likely to find a C89 compiler for it than a C99
one. If there isn't a C compiler for it then it will be easier to write
a C89 compiler for it first. Having Lua strictly depend on C99 features
would delay or maybe even be a blocker for porting Lua to those
systems.

My personal example would be the Open Watcom C compiler which is still
C89, but with a minimal patch it can cross compile Lua 5.4 for 8086 and
i386 CPUs and target operating systems like PC-DOS 2, OS/2, Windows 95,
and even a completely static Linux ELF binary.

If Lua 5.4 was already a C99 codebase this would have been much more
difficult as Watcom C and many other compilers don't have a C99 front-
end while Clang/GCC dropped their i386 back-end a long time ago (and
never had a 8086 one). There's been talk recently about dropping i486,
ia64, m32c etc... back-ends from Linux/GCC communities as well. It's a
problem that will only grow with time.
> > https://groups.google.com/d/msgid/lua-l/CAL2n1twMcaVKu3y8sUHD9mGVv4YRLu1ShDUUA4K1dkRhgiAObg%40mail.gmail.com
> > .

云风 Cloud Wu

unread,
Aug 30, 2025, 8:46:18 PM (8 days ago) Aug 30
to lu...@googlegroups.com
Roberto Ierusalimschy <rob...@inf.puc-rio.br> 于2025年8月31日周日 02:17写道:
>
>
> Among others, Microsoft Visual Studio C in not fully compatible
> with C99. But it would be helpful to hear what others have to say.

msvc may never fully support c99, they chose c11.

https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-support-arriving-in-msvc/

So, c11 would be a better choice than c99 as a baseline ?

I'm not against c99, but I also think c89 is cool and gives users more
choice in compiler selection,
for example, we can use any c++ compiler , which can compile c89 code as c++ .

--
http://blog.codingnow.com

sur-behoffski

unread,
Aug 31, 2025, 12:36:45 AM (8 days ago) Aug 31
to lu...@googlegroups.com
On 2025-08-31 03:47, Roberto Ierusalimschy wrote:
>> This has likely been discussed previously, but I would like to ask why the
>> project is using C89 as a baseline, which is now rather long in the tooth;
>> even C99 is 27 years old at this point (I've been using it for over 25
>> years since GCC first added support for it).  [...]

I've been playing with a C code program that comes from early Unix.
Separately, I've been very impressed by Gerard Holzmann of JPL, and
in particular how they managed to pull off landing Curiosity on Mars
(over 3 million lines, mostly C). In particular, "software
inspections", which (I believe) IBM used to validate every line of
the Space Shuttle code, was infeasible by several orders of
magnitude to process every line of code in the Mars mission.

I believe Gerard was a principal author of some coding standards at
JPL, including the "Power Of Ten": Ten coding standards that were
*not negotiable* because bugs had occurred in field-deployed
products that would not have occurred if these standards had been
followed.

The JPL coding standards were enhanced/extended to accommodate
other items, notably MISRA standards for automotive/other real-time
safety-critical software.

See especially Holzmann's talk on "Mars Code":

https://www.youtube.com/watch?v=16dQLBgOwbE

----

Tying this back to C89/C99, the standards demanded C99, first with
all warnings as errors, and eventually even requiring -wpedantic.
Furthermore, the infrastructure use a variety of compilers and
other code validation tools. (Many of the tool-based items in the
2012 effort have since been incorporated into e.g. gcc-15.2, which
is the compiler I currently run on my development machine.)

----

In my project, I've tried following these standards, first
limiting myself to strict C89, but found myself needing to use
pragmas/escape mechanisms too often. Changing to strict C99 fixed
these edge cases.

So, in summary, I tried very hard to work with C89 compliance, but
eventually had to cave in and use C99 as a baseline. My vote is for
Lua to move to strict C99 compliance sometime in the next few years.

cheers,

sur-behoffski (Brenton Hoff)
programmer, Grouse Software

Родион Горковенко

unread,
Aug 31, 2025, 1:23:33 AM (8 days ago) Aug 31
to lu...@googlegroups.com
Andrew, Hi!

>> In perspective, probably, C89 support isn't going to last forever.

> Not clear for what reason.

Sorry for not clarifying this.

E.g. for the reason shown by Roger and hinted by Roberto - sticking with C89 requires some
extra efforts (though comparatively minor) both for general language development and for
users targeting some specific modern systems. Switching to newer standard will in turn make
those people who want to use older compilers spending more efforts (perhaps, also promoting some
branch or patch as you suggest). Thus it is just the choice - which share of users will have these
extra efforts to spare. I'm big fan of the older systems myself, but I suspect that vintage-compatibility
may somewhat hamper the evolution of the language and its wider acceptance by modern users.

Anyway, of course, all this is guessing and it is quite difficult to measure the effect caused by either approach.

Andrey Dobrovolsky

unread,
Aug 31, 2025, 2:58:03 AM (8 days ago) Aug 31
to lu...@googlegroups.com
Rodion wrote:

> sticking with C89 requires some extra efforts (though comparatively minor) both for general language development

Indeed, Lua's authors have already performed these efforts successfully.

> and for users targeting some specific modern systems.

This part I don't understand. Let me assume that we are talking about
Lua C API only. Lua sources are compiled with the help of some
compiler into liblua. The user links her/his code with the help of the
corresponding headers. Maybe an example of extra efforts to be
performed from her/his side?

Regards,
Andrew

нд, 31 серп. 2025 р. о 08:23 Родион Горковенко <rodio...@gmail.com> пише:
> To view this discussion visit https://groups.google.com/d/msgid/lua-l/CAL2n1twdDzFi1r2HbwGAtv91hkToDVC1%3Dy8gJ6wRbxoa5ccEjA%40mail.gmail.com.

Roger Leigh

unread,
Aug 31, 2025, 4:17:22 AM (7 days ago) Aug 31
to lu...@googlegroups.com

Hi Roberto,

Regarding Microsoft Visual Studio/Visual C++. It's technically true that it is not fully C99 compliant. However, in practice it supports all of the C99 features which Lua would require, today, to drop C89 support.

I've been developing various open source projects with MSVC support over the years, starting with VS2008.  My experience was that it only really became usable for C99 code with VS2015 which added <stdint.h> and <inttypes.h> and a conforming snprintf; earlier versions lacked the headers but had a non-standard snprint implementation (_snprintf).  With VS2019 it gained some more C99 features, maybe some of the string formatting/parsing functions.  So for all intents and purposes, with the patches proposed here, Lua will build with VS2022 (confirmed with local and CI testing), and it should also build with VS2019.

Regarding the comments in the thread you linked to (http://lua-users.org/lists/lua-l/2022-11/msg00026.html), the comments Viacheslav Usov made about Visual Studio match what I've said above since he is referring to VS2019 having the needed C99 support. For users who really need to build on older versions, it should be patchable to build back to VS2015 without much effort. IMO anything older than that, which is thoroughly obsolescent for out of support versions of Windows, isn't something that is justifiable for an open source project to spend any time supporting, not least of which are the effort and resources required to test all of these old versions.

Wilfred Nilsen made a comment about embedded systems using old C89 compilers. Historically this was certainly true. Today, I think almost all current parts will have a C99 toolchain provided. I have worked in this field the last 7 years, and I've yet to see a non-C99-conforming compiler. I've used GCC cross-toolchains, IAR (ARM, MSP430), Keil and other less common toolchains, and they all supported C99 without exception. Heck, IAR even supports C++17 with a full embedded C++ standard library, as do the GCC cross-toolchains. While there may still be some vendors who ship ancient compilers, they are a distinct minority, and I don't think it should be used as a justification for keeping Lua stuck on C89. Most parts which have sufficient FLASH and RAM to host a Lua environment will have a C99 toolchain available. One thing which is often lacking in these discussions is concrete detail. Which parts and which compilers are problematic? I acknowledge that such parts must exist, but I've never encountered them personally. I've used MCUs and APs from Atmel, Analog, Nordic, TI, ST and NXP, and never once encounted a problem with C99. And I've run Lua on quite a few of them ;-)

As an example of a previous C99 conversion I did for the libTIFF project in 2021, you might find the context and discussion interesting. This was done in two steps, initially optionally using the C99 headers and features if present, and then as a followup using them unconditionally. The two steps were due to use of Autoconf/CMake and would not apply to Lua--it was primarily for staging the changes for managing the migration, testing and review. I would have liked to have linked to some of the relevant mailing list discussion, but unfortunately the archives went offline for this period.

https://gitlab.com/libtiff/libtiff/-/merge_requests/185 (build system work and preparation; includes detailed toolchain information in the discussion, and built with Linux, Windows (VS2019, Cygwin and MinGW))

https://gitlab.com/libtiff/libtiff/-/merge_requests/205 (main conversion)

https://gitlab.com/libtiff/libtiff/-/merge_requests/?sort=created_date&state=merged&search=c99 (list of small followup changes to complete the migration)

In the patchset I attached I've done a similar migration, but not replaced internal types with standard types e.g. replacement of l_uint32 with uint32_t; there are a number of additional cleanups which could be done as a followup exercise.

Kind regards,

Roger

Berwyn Hoyt

unread,
Aug 31, 2025, 5:53:21 AM (7 days ago) Aug 31
to lu...@googlegroups.com
Moving to C99 would be excellent IMHO.

Lourival Vieira Neto

unread,
Aug 31, 2025, 8:12:24 AM (7 days ago) Aug 31
to lu...@googlegroups.com
It would definitely make my life easier =).

--
Lourival Vieira Neto

Roberto Ierusalimschy

unread,
Aug 31, 2025, 10:57:55 AM (7 days ago) Aug 31
to lu...@googlegroups.com
> The reason for bringing it up is that I've repeatedly run into problems
> with the codebase when cross-compiling, usually for 32-bit ARMv7 or v8, but
> there are also a host of papercuts when using Lua on regular systems as
> well.
>
> * luaconf.h goes through a very complex amount of preprocessor logic to
> determine type sizes, format strings etc.  But the assumptions it makes
> don't hold for all compilers and platforms and this can be subtly or
> unsubtly wrong, leading to bad behaviour at runtime.  [...]

Could you tell us exactly what problems you had?

-- Roberto

Wilfred Nilsen

unread,
Aug 31, 2025, 1:03:29 PM (7 days ago) Aug 31
to lu...@googlegroups.com

> Wilfred Nilsen made a comment about embedded systems using old C89
> compilers.

We actually decided to move forward with C99, in part because some of
the auto-generated code we rely on is only emitted for C99. Indeed,
there are still a few legacy embedded systems locked into C89, but by
2025, these cases will be rare and increasingly niche. For the vast
majority of MCUs, C99 toolchains are now standard, so the tradeoff makes
sense :-)

-Wilfred


Warner Losh

unread,
Aug 31, 2025, 1:22:25 PM (7 days ago) Aug 31
to lu...@googlegroups.com
So one thing to consider... Back in the day (like early 2000s) I was able to do the important parts of C99 with a C89 compiler. I had a custom snprintf, inttypes.h, etc. While the .h files themselves were highly unportable, it was enough to compile c99 code that I had on c89. The code didn't hit any of the edge cases that are poorly defined in c89 but well defined in c99 (or if it did,we never discovered it). This was useful for deploying to an older embedded platform (PIC maybe, or MIPSish) when we'd standardized on C99 since the main compiler we had (for FreeBSD and Linux systems) supported it.

So "not supporting c99" isn't the end of the world were Lua to require C99 APIs. They've been back ported to C89 for 25 or more years (I say more, because many came from C89-level compilers, or were similar to what was provided: 4.4BSD had u_intXX_t in the early 90s, for example).  It may be a little bit of legwork to port, but you should be able to do it with only your own .h files. This is a reasonable burden to place on ancient systems that want to run Lua. Many of them are a bit small for Lua anyway. Z80s are too small (though there is a Lua VMs for them). 8086-class would generally have enough memory. So that puts the dividing line in the 80s somewhere, which is a reasonable lookback.

Warner

Roger Leigh

unread,
Aug 31, 2025, 5:04:34 PM (7 days ago) Aug 31
to lu...@googlegroups.com

Yes, certainly.  These are just what I have to hand I can recall this evening.

1. The first isn't a Lua problem, it's a bug in the printf implementation of GCC newlib-nano which omits "long long integer" formatting for code size reasons.  If you build with the defaults, integers print out "%lld" as "ld" without the number:

random seeds: 1756670153, -2147481100

vs

random seeds: ld, ld

Nothing Lua can reasonably do with this, though basing the default upon e.g. "sizeof(void*)" would give you the native size.


2. The second relates to interoperability with other libraries and the host application.

With the GNU ARM Embedded toolchain (GCC 14.2) building for ARMv8m (Cortex-M33), we have the following typedefs:

uint8 -> unsigned char

uint16_t -> unsigned short

uint32_t -> unsigned long

uint64_t -> unsigned long long

and similarly for the signed variants of each.  There is no use of "int" in the fixed-width types.  However, if you were to use LUA_32BITS you would get:

#if LUA_32BITS         /* { */
/*
** 32-bit integers and 'float'
*/
#if LUAI_IS32INT  /* use 'int' if big enough */
#define LUA_INT_TYPE    LUA_INT_INT
#else  /* otherwise use 'long' */

That is, the Lua 32-bit integer type and the application 32-bit integer type can mismatch.  While they are the same size, they are not directly convertible.  This then necessitates a lot of typecasts and this is especially problematic with -Wconversion -Werror.  Incorrect use of casts could lead to unintentional narrowing.  [It's equally annoying with size_t which is "unsigned int" and not uint32_t.]

This is again not strictly a Lua problem--it's an interoperability issue at the boundary between Lua and the host application, including any custom libraries it provides.  This is fixable by setting LUA_INT_DEFAULT correctly.  But because this is a platform-specific detail, it might then break when you build for a different board with a different processor!

But using the same standard sizes on both sides eliminates the problem entirely.


3. Related to (2), the reliance upon int/long/long long is ambiguous when we don't know what size these are.  In quite a few places we are doing quite a bit of work bitshifting to determine how many bits we have to work with.  This ambiguity is removed at a stroke by using the fixed-width integer types.


4. Correctness, robustness, safety and static analysis.  This was touched on by another poster relating to the use of macros vs inline functions.  I'm very interested in improvements which can improve all of these.  While this wasn't part of the patchset I sent, it's really doing the groundwork for potential future changes on top of it once C99 is available to be used.  Inline functions bring type-safety, are reachable with a debugger, have no added overhead, and are better for static analysis of the codebase.  Reducing the number of typecasts also makes it possible to spot problems which are masked, since the static analyser assumes any typecasts you add are correct.  This becomes possible when the types are all standard known sizes.  And the simplification of the codebase is also a benefit for this as well.  Every need for an extra typecase, as mentioned above, is a potential bug which is most likely hidden from static analysis.

Regarding conversions, I actually build Lua with C++17 for the increased stringency around numerical conversions (-DLUA_LANGUAGE_SUPPORT=CXX with the CMake build).  And run inline static analysis:

The Lua codebase is of very high quality, so there aren't any serious warnings, but there are a number of suggestions.  I had to hunt to find one (minor) potential problem (unreachable code).  But if we have to make efforts to verify correctness, C99 is a small step along the way.  Internally, I may well be using C++ features such as "constexpr" and "enum class" in addition to inline functions (which have better semantics in C++) to improve the headers and again make compile-time error checking more robust and static analysis more effective.  This is likely a much more controversial set of changes to upstream, so I most likely won't do this unless it's wanted!  But I can look at making them available for anyone who is interested.


Kind regards,

Roger


Sainan

unread,
Aug 31, 2025, 9:43:00 PM (7 days ago) Aug 31
to lu...@googlegroups.com
> I had to hunt to find one (minor) potential problem (unreachable code)

I think you just found a false-positive. See attachment.

-- Sainan
image.png

bil til

unread,
Sep 1, 2025, 1:00:23 AM (7 days ago) Sep 1
to lu...@googlegroups.com
Am So., 31. Aug. 2025 um 23:04 Uhr schrieb Roger Leigh <rleig...@codelibre.net>:
2. The second relates to interoperability with other libraries and the host application.

That is, the Lua 32-bit integer type and the application 32-bit integer type can mismatch.  While they are the same size, they are not directly convertible.  This then necessitates a lot of typecasts and this is especially problematic with -Wconversion -Werror.  Incorrect use of casts could lead to unintentional narrowing.  [It's equally annoying with size_t which is "unsigned int" and not uint32_t.]

3. Related to (2), the reliance upon int/long/long long is ambiguous when we don't know what size these are.  In quite a few places we are doing quite a bit of work bitshifting to determine how many bits we have to work with.  This ambiguity is removed at a stroke by using the fixed-width integer types.

... but this does not depend on C89 or C99... you can define your own variable types with typedef command also in C89.

Misusing "int" for "nice code switching" between 32 and 64 bit programs is meanwhile quite popular, as MS Visual Studio C uses this to enable quite easy uprgrade of 32 bit code to 64 bit world: It kept "int" to be 32 bit, also in 64 bit code, this is very useful and important for fast "uppimping" of 32 code to 64 bit world. Just of course this violates the "typical C rule", that "int" should be the stadard CPU register type.... .

long on the other side is typically ALWAYS 32bit as I would assume... I hope I am correct :).

A further sligthly nerving thing in the "world of types" is that the "signed ambiguity" of char type ... . Depending on Compiler settings this can be either signed or unsigned... .

... but this all has not much to do with selection C89/C99 ... you run into such problems in ANY more professional code, also in C99... .

Roger Leigh

unread,
Sep 1, 2025, 2:44:56 AM (7 days ago) Sep 1
to lu...@googlegroups.com
On 01/09/2025 02:42, 'Sainan' via lua-l wrote:

>> I had to hunt to find one (minor) potential problem (unreachable code)
> I think you just found a false-positive. See attachment.

I took a second look, and it's more subtle than that.  It does not
trigger if lua_Number is a double.  It does trigger if lua_Number is a
float.  The static analysis is dependent upon how Lua has been configured.


Kind regards,

Roger

Sainan

unread,
Sep 1, 2025, 3:09:35 AM (7 days ago) Sep 1
to lu...@googlegroups.com
> It does not trigger if lua_Number is a double.

So, it does trigger if lua_Number is a float? A float can definitely also be NaN, hence a value that is not equal to itself. That would also be a bug with your static analyser.

-- Sainan

rolf.kal...@kalbermatter.nl

unread,
Sep 1, 2025, 4:24:04 AM (6 days ago) Sep 1
to lu...@googlegroups.com, lu...@googlegroups.com





On Monday, 1 September 2025 at 07:00:09 +02:00, bil til <bilt...@gmail.com> wrote:
long on the other side is typically ALWAYS 32bit as I would assume... I hope I am correct :).

Not really. "long" on GCC at least under *nix (not sure about GCC on MS systems) is a 64-bit integer when compiling for x86_64.
The C standard only says that long must be at least as large as int.

1 == sizeof( char ) <= sizeof( short ) <= sizeof( int ) <= sizeof( long )

It would seem logical to have long be a 64-bit integer when compiling for 64-bit, but Microsoft choose for backwards compatibility to keep long a 32-bit type. They initially introduced a Microsoft specific _int64 type when 64-bit was required, independent of what memory model was targeted, but then eventually added most of the C99 standard in VS 2010 (MSC 16.0), although it wasn't really a full implementation of C99 but rather due to adding C++ features from the C++ TR1, which included many C99 features too, and eventually resulted in the C++11 standard.

Rolf Kalbermatter

Roberto Ierusalimschy

unread,
Sep 1, 2025, 10:20:51 AM (6 days ago) Sep 1
to lu...@googlegroups.com
> uint8 -> unsigned char
>
> uint16_t -> unsigned short
>
> uint32_t -> unsigned long
>
> uint64_t -> unsigned long long
>
> [...]
>
> But using the same standard sizes on both sides eliminates the problem
> entirely.

All these types are optional in C99. Therefore, they should not be used
in a software that aims portability the way Lua does. That is, even if
we moved to C99, we would not use any of these types in the code, but
instead would use either the int_leastN_t or int_fastN_t variants.


> 3. Related to (2), the reliance upon int/long/long long is ambiguous when
> we don't know what size these are.  In quite a few places we are doing
> quite a bit of work bitshifting to determine how many bits we have to work
> with.  This ambiguity is removed at a stroke by using the fixed-width
> integer types.

Again, C99 does not ensure fixed-width integer types.

Moreover, the Lua API never uses long nor long long directly. It uses
'int' and lua_Integer (and corresponding unsigned). If you need/want,
it should be trivial to change luaconf.h to define lua_Integer to be
exactly the type you want it to be.


> 4. Correctness, robustness, safety and static analysis.  This was touched
> on by another poster relating to the use of macros vs inline functions. 
> I'm very interested in improvements which can improve all of these.  While
> this wasn't part of the patchset I sent, it's really doing the groundwork
> for potential future changes on top of it once C99 is available to be
> used.  Inline functions bring type-safety, are reachable with a debugger,
> have no added overhead, and are better for static analysis of the
> codebase.  Reducing the number of typecasts also makes it possible to spot
> problems which are masked, since the static analyser assumes any typecasts
> you add are correct.  This becomes possible when the types are all standard
> known sizes.  And the simplification of the codebase is also a benefit for
> this as well.  Every need for an extra typecase, as mentioned above, is a
> potential bug which is most likely hidden from static analysis.

Lua is completely C99. Even if it does not use several C99 facilities,
it does not preclude you from using them in your code.

-- Roberto

Reply all
Reply to author
Forward
0 new messages