tinycc-devel
[Top][All Lists]
Advanced

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

[Tinycc-devel] TinyCC on Windows & some suggestions


From: Robert Schlicht
Subject: [Tinycc-devel] TinyCC on Windows & some suggestions
Date: Sun, 10 Mar 2024 17:59:56 +0100

At our university we offer a course where we program simple spatial simulations 
in various programming languages, one of them being C, for illustrating 
close-to-the-machine programming concepts. We here need a C implementation that 
is small (since it’s accessed over a network), works out of the box on Windows 
computers (since our students are beginners) and runs fast (so compiler errors 
are available instantaneously). We do not need advanced developer tools, and 
code running three times slower is acceptable because that is still faster than 
scripting languages.

TCC is obviously a good option here, and for our course starting in April of 
this year, I put together a package https://rschlicht.eu/tc-ide.zip that 
includes a minimalist IDE running TCC and a very basic form of a C standard 
library, all contained in a standalone executable tc-ide.exe. The library is 
just headers that directly access the Windows API (no runtime needed) and 
should satisfy the requirements of a conforming freestanding implementation, 
while also including common memory, file, math and the printf family of 
functions. (If anyone finds this useful, I’ll gladly contribute it to the TCC 
project.)

The executable is compiled by itself, although this currently requires a few 
hacks and workarounds to get it working as desired. I list these here as 
suggestions for improving TCC:

(1) For using TCC as a library, it would be nice if it did a more thorough 
cleanup:
– In a few places exit() is called in case of failure, but terminating the 
program is not very user-friendly; cleanly propagating failure or even some 
longjmp hacks might provide a better solution. [tc-ide does the latter, while 
patching function calls to keep track of memory and open files.]
– Another problem I encountered is that TCC does not always properly restore 
the state of the global variables; compiling the following code fragment the 
first time produces an error message (as it should), but the second time it 
causes an exception (which I assume is a bug):
    void nothing(void) {for ( ; ; ) break;}  void garbage(void) {switch
[The workaround in tc-ide is ugly but straightforward: Make a copy of the 
memory block containing all global variables, and restore this block after TCC 
returns.]

(2) I really appreciate that TCC can directly link to functions in Windows DLLs 
with no auxiliary .lib file and that it even supports directives like #pragma 
comment(lib,"kernel32"). The current implementation of the DLL lookup with a 
huge number of lseek & read calls (via read_mem() in tccpe.c) may be 
inefficient on some file systems. [tc-ide avoids this issue by creating file 
mappings in memory and redirecting lseek and read to those memory buffers, 
which it has to deal with anyway to access the embedded headers.]

(3) The C23 preprocessor directive #embed would be of help for embedding 
headers and other files as byte arrays in the program. [tc-ide currently does 
this by providing a non-standard feature with a custom notation like #include 
"stdlib.h#".]

(4) TCC uses fixed buffer sizes for file paths in certain places. For example, 
libtcc.c has 260(=MAX_PATH) in config_tccdir_w32() and _fullpath(), 1000 in 
tcc_add_systemdir() and 1024 in tcc_add_library_internal(), while tccelf.c has 
1024 in getcwd(). Windows has been supporting long file paths for quite a while 
now, so it might be better to allocate those buffers dynamically: 
https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation

(5) Some rarely used C library functions could perhaps be replaced to make the 
code less dependent on such features. Examples are the single use of alloca() 
in libtcc.c to set up a buffer and the use of scanf() in tccpp.c to convert the 
TCC version string into a number. [tc-ide here provides stubs.]

(6) It would be useful to allow the user to set the entry point symbol (either 
the one called by the OS or the one called by the startup code), like other 
compilers do. [tc-ide provides its own version of _start(), which simply calls 
main().]

(7) Additional observations:
– In tcc_new() (tcclib.c), checking the return value of tcc_mallocz is probably 
redundant.
– In tcc_close() (tcclib.c), I do not understand why the test is ">0" instead 
of ">=0". Typically 0 is stdin, but maybe the code should not rely on that.
– The protection of InitializeCriticalSection() in tcc.h is not thread-safe and 
can lead to a race condition.
– In Windows, the semicolon ';' can appear in file names and is therefore 
perhaps not an ideal PATHSEP path separator character (despite that fact that 
it is still used in that function in the Path environment variable); a double 
null-terminated string could be a better choice.

Let me conclude with a question on the licenses. As I understand it, TCC is 
licensed under LGPL, although there is also a more permissive RELICENSING 
statement, but I assume this is irrelevant due to the various contributions by 
authors not listed there. Is that so, or am I missing something?

Robert



reply via email to

[Prev in Thread] Current Thread [Next in Thread]