Over 20 Years of C99: Making a Concession

In the interest of bragging rights, we've tried to say that Ren-C builds on C89.

Not quite true, since we use // comments instead of just /* */ comments. But a lot of compilers before C99 supported that, and you could just strip them out.

Also not quite true because we don't declare all locals at the top of blocks in a function. But a lot of compilers before C99 supported that, and if not you could write a preprocessor to do it.

But a big feature that would helps if we permitted using it is C99 variadic macros. It means we can automatically add terminator signals to API calls:

So instead of writing things like:

if (rebNot("action?", rebQ(main_startup), rebEND))
    rebJumps("panic-value", rebQ(main_startup), rebEND);

We can say:

if (rebNot("action?", rebQ(main_startup)))
    rebJumps("panic-value", rebQ(main_startup));

Right now we support both modes, but hold off on using the nicer mode in the internal implementation.

The C++ build checks to make sure that the rebENDs are there if you mark a file as "C89-compatible" and that it should have them. So that makes it easier to not forget them if you meant them to be there. But they're still an eyesore.

I Think It's Time to Adjust The Rule

The original idea was that "public-facing" code would all use the nice mode, but we would bear the burden of rebEND in the internal code for the sake of making it compile on older systems.

However, the code for the interpreter itself is supposed to be a showcase of its features. If you are looking at the startup sequence in main.c and are hit with these rebEND-based API calls, that's will prevent appreciating it fully.

We should preserve the ability to call these APIs from C89. e.g. you should be able to include libRebol from a C89 compiler. That API file should have a mode you can use to include it in a C89 program, where you have to provide the rebENDs explicitly.

But the internal implementation should allow the usage of the macro form. Not leveraging it makes reading the code for Ren-C itself not as pleasing as it should be. I want the code for stepping through the boot process and extensions to make the best impression. And rebEND detracts from an otherwise profoundly distinct experience.

The answer for people who want to build the sources on a very old compiler would be the same answer as for those who want to build it on a system that doesn't have //-comments...run the source through a preprocessor. Expand the rebXXX() macros to make a new version of the source, and then compile that.

Seems fair.

2 Likes