cmacroswarningsg-code

Why NIST RS274NGC G-Code Interpreter uses this code style?


I just compiled NIST RS274NGC G-Code Interpreter and saw unbelievable 890 warnings from gcc.

200 of them were caused by this array:

char * _rs274ngc_errors[] = {
/*   0 */ "No error",
/*   1 */ "No error",
/*   2 */ "No error",
/*   3 */ "No error",
/*   4 */ "A file is already open", // rs274ngc_open
<...>

which, according to my basic understanding, should be const char *.

Then I saw these macros (they actually appear several times in different .cc files):

#define AND              &&
#define IS               ==
#define ISNT             !=
#define MAX(x, y)        ((x) > (y) ? (x) : (y))
#define NOT              !
#define OR               ||
#define SET_TO           =

Then I saw a lot of warnings suggest braces around empty body in an 'else' statement [-Wempty-body] caused by really strange control flow altering macros like this (yes, with dangling else!):

#define PRINT0(control) if (1)                        \
          {fprintf(_outfile, "%5d \n", _line_number++); \
           print_nc_line_number();                    \
           fprintf(_outfile, control);                \
          } else

Report suggests that

A.5 Interpreter Bugs

The Interpreter has no known bugs

All of that makes me wonder - why is it written so strangely? I can understand macros like PRINT0 - error handling in C can be a real pain - but why would anyone use SET_TO instead of =?

I can believe that all this code was generated but couldn't it be generated in warning-free way?

I'm not an expert in any way, I'm just really curious.


Solution

  • As Hans and Foad point out, this was the norm back then. It's referred to as K&R C, after the inventors of the language, Brian Kernighan and Dennis Ritchie. (Note that K&R C can also refer to a formatting style they popularized while writing the first book about the language.)

    K&R C was quite forgiving of things that a compiler in C99 or C11 mode would treat as UB (undefined behavior) or a flat-out syntax error, such as defining a function taking args without specifying the types of the args. Back then, such a function was assumed to take int args.

    IIRC the first major overhaul of the language was ANSI C '89; computer power, compilers, and the popularity of the language had changed drastically between its invention and that standardization.

    If antiquated C interests you, you may wish to look at the source of the Bourne shell. Quoting Wikipedia's Bourne Shell article:

    Stephen Bourne's coding style was influenced by his experience with the ALGOL 68C compiler ...

    ... Bourne took advantage of some macros to give the C source code an ALGOL 68 flavor. These macros (along with the finger command distributed in Unix version 4.2BSD) inspired the IOCCC – International Obfuscated C Code Contest.

    An actual example of the code can be found on rsc's site, and (what I assume is) complete source can be found here.


    By the way, if you think the number of warnings you got is a lot, you should try turning on additional warnings. There are plenty that are reliable and useful but aren't on by default, though I don't have an up-to-date list of them. -Wall -Wextra would be a decent start.