C is an awesome simple language perfect for close-to-hardware programming, but the preprocessor sucks in comparison to modern languages.

Is there an alternative/add-on to the c preprocessor that adds modern features to C pre-processing (eg import vs includes)? In particular, I'm looking for namespaces (or something close to that), a readable macro language, and a more powerful macro language (with reflection).

Or do I need to look in to viable alternatives to C for doing embedded programming (my own projects, not contract work where I take on or pass off project)

I am aware of D, but haven't really looked into using it for embedded.

This question appears to be off-topic. The users who voted to close gave this specific reason:

"Questions asking us to recommend a tool, library or favorite off-site resource are off-topic for Programmers as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it." – gnat, GlenH7, MichaelT, Kilian Foth

It could be worse, it could be assembly. What features are you "missing" from C, it could be that a dev environment extension (Eclipse plugin or visual studio automated steps) can help close the gap?
–
Patrick HughesJul 9 '11 at 17:56

3

This is not a preprocessor limitation but a language limitation. You need to use the C mindset - this is embedded after all.
–
user1249Jul 9 '11 at 18:00

3

Careful what you ask, you should be. Down this path lies, evil. For I have trod this way before, and I have looked evil in its eye. And its name was ratfor.
–
Mark MannJul 9 '11 at 18:37

4

Michael, you're not going to get a lot of sympathy among programmers when you say that C isn't "modern enough." It's not supposed to be modern. C is what it is; you can either accept it for what it is or reject it. And don't think that eLua is going to save you; mobile platforms have rather low power CPUs, and even Lua's performance isn't going to be enough for anything serious with JIT compilation. Of course, there's LuaJIT, which compiles for ARM platforms...
–
Nicol BolasJul 9 '11 at 22:30

4

@michael: the preprocessor does do what it is supposed to do. It builds token lists for the C tokenizer. That's what it is for. Your problem is that it doesn't do things the way you think they should be done, based on a standard you have created yourself. Consider "import." You can't do that with a preprocessor; you need language-level support to make anything like that work in any way different from include. import is not a part of the preprocessor; it's a part of the compiler.
–
Nicol BolasJul 10 '11 at 2:15

5 Answers
5

If you do not like programming in C - with or without CPP - you essentially have only a few options for embedded programming:

Learn assembler for the platform. Low productivity, non-portable.

Find a suitable language which can generate C source which you then compile and deploy. This will be painful when you need to debug stuff because the debugger is not referring to your original source but the generated C.

Brain-wash and decide to like to learn C.

Based on my experiences with all three approaches, I would recommend you go for the brain wash. In the long run the pain will be the least.

edit: eLua looks nice, but does it run correctly on your platform? Essentially you need to be prepared to debug eLua too.

I do like programming in C. I am stating that the preprocessor is a giant pile of sh- compared to the meta stuff in java, python and anything else created after 64K was considered enough.
–
michaelJul 9 '11 at 19:20

No, that's how the C preprocessor works. C doesn't have to have anything to do with it.
–
michaelJul 10 '11 at 2:09

4

The C preprocessor is part of the C language specification - you can't have one without the other, unless you want to write code in a non-standard, non-portable C-like language.
–
Paul RJul 10 '11 at 6:39

I'm not sure I understand, the preprocessor is very simple replacement macro type system. You hardly have to use it if you don;t want to (eg const int or inline function instead of #define).

As you specify includes as a problem, I still don't see what the problem there is - you include a header file and it contains all the definitions of the .c compilation unit. Isn't that what #import does, but for higher-level languages that want objects imported from a binary and the definitions translated from the metadata? #include is the source-code equivalent of that.

you can't get accidental recursive imports, but you can with includes. Which is only a short coming because the preprocessor was defined when memory usage defined feature sets of development tools.
–
michaelJul 9 '11 at 17:59

@michael: Is this your biggest problem? You want it to protect you from accidents you might make? I've often wished there were a cpp debugger, but somehow I managed without it.
–
Mike DunlaveyJul 9 '11 at 20:05

@Mike, a cpp debugger?
–
user1249Jul 9 '11 at 20:39

6

You can't get accidental re-includes if you use the standard form of #ifndef FILE_H ... #define FILE_H ... #endif FILE_H as the first two lines and last line of the include file. This way it will only be included once, not matter how many times it is invoked.
–
Mark MannJul 10 '11 at 2:16

2

@Thorbjørn: A cpp debugger. The preprocessor is an interpreter; the output is the intermediate code. It has IF statements. Instead of subroutines, it has #include and macro expansion. Haven't you ever wondered how on earth all those MS Windows include files managed to generate all the things they do? It really would be nice to have a way to single-step the preprocessor, examine defined symbols, see which branch of #ifs are taken, show the stack of #include and macro expansions. Rather than just a "black box"?
–
Mike DunlaveyJul 10 '11 at 2:41

Why not write your own preprocessor? Write it in C, with no preprocessor commands, and ship your preprocessor along with your source code.

Of course, then you'll have to face up to the fact that the C preprocessor is a PRE-processor, not a run time environment. AFAIK the preprocessor generates C code. If you can't do it in C code then you can't do it with any preprocessor.