Hacker News new | ask | show | jobs
by drblast 5271 days ago
I don't know why people don't seem to think of this when confronted with the limitations of the standard C preprocessor, but Perl or Lisp both make excellent C preprocessors.

You aren't required to only use the C source code transformation tools that a default install of GCC provides.

6 comments

Because it moves you to a whole new circle of hell from the very common C preprocessor one that every C developer on the planet has been in at one point or another.

If you're using VS, you're going to want to use the included pre-build steps in the vcproj to generate the source. Unfortunately, you can't just edit the source in place, unless your team is absolutely in love with your SCS' rollback capability. So that means that in order to edit the code, you need to open it up in either another project, or open it outside the IDE's solution environment.

It also removes the ability to do partial rebuilds, since every file will be necessarily touched by the preprocessing script before compiling, so it's a "new" file as far as the IDE is concerned.

Debugging becomes a chore, because the code in source control is not the code that was compiled, breaking line counts and breakpoints.

Finally, it's a deployment nightmare for your build staff, since they need to make sure that everyone is standardized on the same perl version, maintain the scripts in addition to the makefiles, and make sure that everyone's dev environment works with it.

For valid reasons the build system is very minimal and the number of external dependencies is limited to 'absolutely necessary', adding another interpreter to the list of dependencies is simply not an option.

But sure, if that's not one of the limitations you're working under then code generation through another language is definitely a possibility.

It introduces a new dependency on a new language that has no relationship to C. For local projects, sure, for projects you want to distribute it's risky.

If you're about to reply it's a risk you'd take... me too, in general. CPP sucks. But not wanting to introduce that risk is a valid choice in many cases.

Using external programs to generate code nontrivially increases the required complexity of your build system, and unless you're targeting Linux only, it isn't really given that users will already have perl installed, much less a lisp interpreter.
nontrivially increases the required complexity of your build system.

No it doesn't. It only requires a single rule in your Makefile. Something like:

    %.c: %.cpre preprocess.pl; ./preprocess.pl <$^ >$@
Which works great if you use makefiles, but for those using Visual Studio for build management, it can be a bit more tricky. First you have to make sure you have perl, then you have to make sure you've got the appropriate build rules in place, then you have to make sure things get built at the right time, etc. It really is nontrivial.
As was already stated: it isn't really given that users will already have perl installed.

The usual workaround for such situations is to add the preprocessed files into source control as well, so they are available when a user is building the code. However, this ends up even more ugly.

None of that has to do with build system complexity.
Yep. Why try to force a tool into a role it was never designed for? You use m4 or just write a preprocessor in any language. If you really want to do complicated lisp-style meta-programming stuff with C, just write another C program to pre-process your C program. It's more work, but it gives you complete control over the syntax.
...or just use Python, Ruby, or Lisp directly?

Doing weird things to a C file (while occasionally useful) is just increasing the technical debt of your teammates later.

(though, we do have a closure-ish macro in our codebase that's pretty nifty, so do as I say not as I do etc.)

    >> If you really want to do complicated lisp-style meta-programming stuff
    > Increases technical debt
    Yep. The sane solution is to just not do stuff like this at all. In rare
    situations it ends up being worth it.
True but this also creates extra dependencies for any project doing this. If you need to be able to compile on various platforms and/or machines doing so can introduce unnecessary complications as a result.