Force compile error if function argument out of range - c

I am restricted to C (cannot use C++). I wish C had stricter type checking.
Is there a way to get compile errors on the commented lines? If it helps, the enum values cannot overlap.
enum hundred {
VALUE_HUNDRED_A = 100,
VALUE_HUNDRED_B
};
enum thousand {
VALUE_THOUSAND_A = 1000,
VALUE_THOUSAND_B
};
void print_hundred(enum hundred foo)
{
switch (foo) {
case VALUE_HUNDRED_A: printf("hundred:a\n"); break;
case VALUE_HUNDRED_B: printf("hundred:b\n"); break;
default: printf("hundred:error(%d)\n", foo); break;
}
}
void print_thousand(enum thousand bar)
{
switch (bar) {
case VALUE_THOUSAND_A: printf("thousand:a\n"); break;
case VALUE_THOUSAND_B: printf("thousand:b\n"); break;
default: printf("thousand:error(%d)\n", bar); break;
}
}
int main(void)
{
print_hundred(VALUE_HUNDRED_A);
print_hundred(VALUE_THOUSAND_A); /* Want a compile error here */
print_thousand(VALUE_THOUSAND_A);
print_thousand(VALUE_HUNDRED_A); /* Want a compile error here */
return 0;
}

In C, enum types are indistinguishable from integers. Very annoying.
The only way forward I can think of is a kludgy workaround using structs instead of enums. Structs are generative, so the hundreds and thousands are distinct. If the calling convention is sensible (AMD64) there will be no run-time overhead.
Here's an example using structs that gets the compile-time errors you wanted. Kludgy, but it works:
#include <stdio.h>
enum hundred_e {
VALUE_HUNDRED_A = 100,
VALUE_HUNDRED_B
};
enum thousand_e {
VALUE_THOUSAND_A = 1000,
VALUE_THOUSAND_B
};
struct hundred { enum hundred_e n; };
struct thousand { enum thousand_e n; };
const struct hundred struct_hundred_a = { VALUE_HUNDRED_A };
const struct hundred struct_hundred_b = { VALUE_HUNDRED_B };
const struct thousand struct_thousand_a = { VALUE_THOUSAND_A };
const struct thousand struct_thousand_b = { VALUE_THOUSAND_B };
void print_hundred(struct hundred foo)
{
switch (foo.n) {
case VALUE_HUNDRED_A: printf("hundred:a\n"); break;
case VALUE_HUNDRED_B: printf("hundred:b\n"); break;
default: printf("hundred:error(%d)\n", foo.n); break;
}
}
void print_thousand(struct thousand bar)
{
switch (bar.n) {
case VALUE_THOUSAND_A: printf("thousand:a\n"); break;
case VALUE_THOUSAND_B: printf("thousand:b\n"); break;
default: printf("thousand:error(%d)\n", bar.n); break;
}
}
int main(void)
{
print_hundred(struct_hundred_a);
print_hundred(struct_thousand_a); /* Want a compile error here */
print_thousand(struct_thousand_a);
print_thousand(struct_hundred_a); /* Want a compile error here */
return 0;
}

You can't do it. In C++ you could overload the function and do some trickery (or use boost::enable_if), or just rely on C++'s type safety making it error out automatically. In C, that doesn't work since function overloading is not supported. And you can't check the value in the function and cause a compile time error, since all values are known only at runtime (as opposed to types).
The C Standard allows compilers to warn about what you do. So you could enable the -Wall -Werror flag and hope gcc will error out. But this is not a general purpose C way.

I think strictly the answer is, "it depends on the compiler". I'm fairly sure that the code is legal C, so by default a C compiler wouldn't/shouldn't complain, but there are probably different options in different compilers that can pick it up.
If this type of error checking is important to you then I suggest investigating C linters/style checkers/static analysis tools which will catch this and other common (and not so common) errors (if you set them up correctly!). It is a bit of work to add these tools into your build process, but if for your project you think catching these kind of things at compile is valuable then the cost is going to be worth it.
Two I would recommend are:
FlexeLint, which is a relatively inexpensive commercial product that I have used to great effect.
An open source alternative would be Splint, but unfortunately it appears to be mostly unmaintained at the moment.
There are more expensive commercial tools such as Klocwork and Coverity.
Adding these kind of tools to your software does take some effort. They are usually extremely flexible and customisable, and you need to make some educated decisions about what behaviours you want to allow, and which you want to disallow in your code base.

You could do it using #defines for your functions and __builtin_constant(x), which returns 1 if x resolves to a constant and 0 if it does not. Note this is a gcc-only intrinsic; I have no idea if there are equivalents on other compilers.

I would argue that the problem isn't as much that C doesn't support strict type checking, as it's that it really doesn't support true user-defined types.
My guess is that most C compilers would translate both of your enums into simple ints or shorts or whatever, and would not do anything beyond that.
So as far as I can tell, the answer would be know.

There's no way C alone can do it because the compiler doesn't know anything except the base types. The usual thing is to use the assert() macro, but that's a run-time check.

Related

if/else strive for logical completeness in single return function

I'm attempting to exist at the crossroads of MISRA C and CERT C and setting the lofty goal of no exceptions. The two rules most against my normal patterns are (paraphrased):
MISRA : A function should only have one return
CERT : Strive for logical completeness
The CERT rule keeps catching me when I have nothing to say in an else. For example:
static int32_t SomeFunc()
{
int32_t retval = PROJECT_ERROR_GENERIC;
retval = ChildFuncOne();
if (retval == PROJECT_SUCCESS)
{
retval = ChildFuncTwo();
}
//Common cleanup
return retval;
}
Assuming there is no specific cleanup for the failure of ChildFuncOne, I have nothing to say in else. Am I missing another way to lay out this function?
Option 1 is an else with an empty body:
static int32_t SomeFunc(void)
{
int32_t retval = PROJECT_ERROR_GENERIC;
retval = ChildFuncOne();
if (retval == PROJECT_SUCCESS)
{
retval = ChildFuncTwo();
}
else
{
// yes, I did consider every possible retval
}
//Common cleanup
return retval;
}
Option 2 is to add a second variable, and then set that variable in the if and the else. Note that I reversed the sense of the if, since that order makes more sense to me. YMMV.
static int32_t SomeFunc2(void)
{
int32_t retval = PROJECT_ERROR_GENERIC;
int32_t finalretval = PROJECT_ERROR_GENERIC;
retval = ChildFuncOne();
if (retval != PROJECT_SUCCESS)
{
finalretval = retval;
}
else
{
finalretval = ChildFuncTwo();
}
//Common cleanup
return finalretval;
}
The problem with option 2 is that it's easy to mix up the two variables that have similar names and uses. Which is where these coding standards make your code more likely to have bugs, rather than less.
The only problem with your code I can find is the obsolescent style function definition. static int32_t SomeFunc() should be static int32_t SomeFunc(void). The former has been obsolescent form in C since some 25-30 years back and also violates MISRA 8.2 for that reason. Other than that, the code is fine and MISRA compliant.
A style comment beyond MISRA is that I would use an enum over int32_t.
Regarding CERT I assume you refer to MSC01-C. This is a fuzzy and unclear rule, with just a bunch of non-related code examples. I would just ignore it.
The corresponding MISRA C:2012 15.7 and 16.1 are much clearer and can be summarized as:
All else if should end with an else.
All switch should contain default.
The rationale is defensive programming and self-documenting code: "yes, I have definitely considered this outcome". Likely this is what CERT C tried (and failed) to say as well. They refer to various "else if with else" rules in their crossref.
This isn't applicable to your code. Nobody requires that every if ends with an else, that would be a ridiculous requirement.
Am I missing another way to lay out this function?
It's sound practice to set the result variable to a known default state at the beginning of a function and later overwrite it if needed. So your function is not only compliant, but also fairly canonical style as safety-related programming goes.
So other than the () to (void), there's no need to change a thing.
My attempt:
static int32_t SomeFunc()
{
int32_t retval = ChildFuncOne();
retval = (retval == PROJECT_SUCCESS)? ChildFuncTwo() : retval;
retval = (retval == PROJECT_SUCCESS)? ChildFuncThree() : retval;
return retval;
}
Basically, the retval is set by the first function, and only if that result is PROJECT_SUCCESS, will the second function get called and set the retval.
If the retval is anything other than success, it remains unchanged, the second function is never called, and retval is returned.
I even show how it can be chained for an arbitrary number of functions.
I'm a bit unclear what you mean bye "common cleanup", so if you need different cleanup operations depending on what functions succeeded and failed, that will take extra work.
You should stop trying to appease the MISRA and CERT gods and just write clear code. The code that you posted is fine. Keep it that way.

MISRA demand a single point of exit for a function for a "lookup table" function

Misra standard demand a single point of exit for a function, but I have the following "conversion" code
typedef enum { CASE_A, CASE_B, CASE_C } my_enum_t;
int my_conv_funct(my_enum_t value)
{
switch(value)
{
case CASE_A:
return 0;
case CASE_B:
return 1;
case CASE_C:
return 2;
default:
break;
}
log_error("ERROR!!!!!");
assert(1==0);
}
Is this valid?
I need to convert it to a single return function?
And what is the best way of handling the default case?
this creates an unreachable code in theory (the error is to warn in case one add a value in the enum and not add a corresponding case)
This is an embedded system btw having those asserts create issues?
Thanks,
Nick
EDITED:
the default case should be never called if there are no errors (for example a programmer add another value in the enum and doesn't add a corresponding case
another options would be to remove the default at all but that violates another misra rule
typedef enum { CASE_A, CASE_B, CASE_C } my_enum_t;
int my_conv_funct(my_enum_t value)
{
switch(value)
{
case CASE_A:
return 0;
case CASE_B:
return 1;
case CASE_C:
return 2;
}
//should never reach this line
assert(1==0);
}
This will generate a warning if I compile and don't specify all the cases in the enum (I think)
Very simply:
int my_conv_funct(my_enum_t value)
{
int result = -1;
switch(value)
{
case CASE_A:
result = 0;
break;
case CASE_B:
result = 1;
break;
case CASE_C:
result = 2;
break;
default:
break;
}
if(result == -1)
{
log_error("ERROR!!!!!");
assert(1==0);
}
return result;
}
Is this valid?
It does not comply with the MISRA rule you described.
I need to convert it to a single return function?
To comply with the MISRA rule, yes.
And what is the best way of handling the default case?
We cannot judge what is "best" for your particular circumstances and use.
This is an embedded system btw having those asserts create issues?
The idea of an assertion is that it helps you find programming errors during development, but (in principle) it gets disabled via build options in code that is intended to be used in production. If that model is followed then the assertion itself probably does not create an issue, but the fact that the function does not return a value in the default case (if assertions are disabled) does. If the program must terminate in the event that the default case is exercised then it should call abort(), or some other function having that effect. Otherwise, it should return a sensible value in the default case.
I would probably write the function more like this:
int my_conv_funct(my_enum_t value)
{
switch(value)
{
case CASE_A:
case CASE_B:
case CASE_C:
break;
default:
log_error("ERROR!!!!!");
assert(0);
break;
}
return value;
}
There is now just one exit point from the function, and if it returns at all then it returns its argument (implicitly converted to type int).
First of all please check this answer: Best practice for compute the function return value. The MISRA-C rule is advisory and I recommend to make a permanent deviation against it. Personally I replace it with a rule such as:
"Multiple return statements in a function should be avoided unless they make the code more readable/maintainable."
The rationale to avoid returning from multiple places inside nested, complex code is sound, but far less so in clean and readable functions.
In your specific case though, I would perhaps have rewritten the function like this (MISRA compliant without ignoring the rule):
uint32_t my_conv_funct (my_enum_t value)
{
uint32_t result;
switch(value)
{
case CASE_A: result = 0; break;
case CASE_B: result = 1; break;
case CASE_C: result = 2; break;
default:
{
// error handling here
}
}
return result;
}
Alternatively (deviating from the rule):
uint32_t my_conv_funct (my_enum_t value)
{
static const uint32_t lut[] = { CASE_A, CASE_B, CASE_C };
for(size_t i=0; i<sizeof lut/sizeof *lut; i++)
{
if(lut[i] == value)
{
return i;
}
}
/* error handling */
return some_error_code;
}
This assuming that the amount of items isn't large, in which case a binary search might be more inefficient.
This in turn assuming that the enum constants don't correspond to 0, 1 and 2 in which case the whole function is nonsense.
The rationale for the MISRA C "single exit" Rule is because it is a requirement for the functional safety standards (eg IEC 61508 and ISO 26262).
It is also Advisory so can be disapplied if the circumstances so require.
My personal view is that a switch statement seldom needs multiple exits - it is easy to structure to avoid them... however there are situations (eg parameter validation) where it may make sense.
--
As an aside, use of assert() is non-compliant with MISRA C as it expands to abort() which is in breach of Rule 21.8 - this is also a very undesirable behaviour in an embedded system (and questionable in a hosted environment)...
--
See profile for affiliation.
The updated question has now been extended to include:
the default case should be never called if there are no errors (for example a programmer add another value in the enum and doesn't add a corresponding case
another options would be to remove the default at all but that violates another misra rule
I disagree...
The default is there as an error trapping mechanism - especially in real-time/embedded systems, data values may change unexpectedly (cosmic rays anyone) and it is a brave real-world engineer that does not protect against the unexpected.
How often has a default or else clause containing a comment /* Can never reach here */ actually been reached?

C89 computed goto (again) how to

I need to code an automata, and I bumped into this old need of a computed goto (ala fortran4 :) )
I need to code this in a portable ansi-C.
I want to stay away from the "don't do that", away from longjmp/setjmp, away from embedded ASM(), away from non ansi-C extensions.
Does anyone know how to do this?
Like I said in a comment, despite your plea to not use anything other than goto, standard C has nothing to offer.
Design your state appropriately, and pass a pointer to it to the handler functions for them to modify. That way the handler can setup the next function to call. Something like this:
struct state;
typedef void state_func(struct state*);
#define NULL_ACTION_ADDRESS (state_func*)0
struct state {
state_func *action;
int value1;
int value2;
};
#define INIT_STATE { initial_action, -1, -1}
state_func initial_action;
state_func handle_a;
state_func handle_b;
int main(void) {
struct state s = INIT_STATE;
while(s.action != NULL_ACTION_ADDRESS) {
(*s.action)(&s);
}
return 0;
}
void initial_action(struct state* ps) {
ps->action = &handle_a;
}
void handle_a(struct state* ps) {
ps->action = &handle_b;
}
void handle_b(struct state* ps) {
ps->action = NULL_ACTION_ADDRESS;
}
I think I got it, I reviewed all the various threads on this topics and I started to agree that that there where no ansi C solutions, yet I found an way to do this that fit my needs. All solution I saw on stackoverflow where based on the idea to 'get' the addr of a label, then stuff it into a table, then index this table and goto, this is both with gcc/clang non ansi extension or the asm extension.
I gave it another try tonite and got this.
In an include file named cgoto.h I have this
#ifndef CGOTO_dcl
#define CGOTO_dcl(N) int CGOTO_##N
#define CGOTO_LE(l) l,
#define CGOTO_LG(l) case l:goto l;
#define CGOTO_def(N) \
if(0){typedef enum {N(CGOTO_LE)} N; CGOTO_##N: switch(CGOTO_##N)\
{N(CGOTO_LG) default:CGOTO_##N=0;goto CGOTO_##N;}}
#define CGOTO(N,i) CGOTO_##N=i; goto CGOTO_##N;
#endif
The usage is like this
#include <stdio.h>
#include "cgoto.h"
int f(int x)
{ //...
CGOTO_dcl(gtb);
//...
# define gtb(L) L(l0) L(l1) L(l2)
CGOTO_def(gtb);
//...
CGOTO(gtb,x);
l0: printf("error\n");
return(0);
//...
l1:return(11);
l2:return(22);
l3:return(33);
}
int main()
{ printf("f(0)=%d f(1)=%d f(2)=%d,f(3)=%d\n",f(0),f(1),f(2),f(3));
}
In this implementation, the cost of jumping is 2 jumps and a switch() that is sequential, then optimisable. So this is reasonably performing compared to function call, a little less performing than &&label solution at the cost of portability.
With this implementation, labels code (semantic actions) are not confined into a switch() so we can implement jump table with shared semantic actions.
The index is assigned to a local goto_table_index, making the function using this re-entrant (multi threadable), though the optimiser can remove altogether this temp assignment.
The 1st Label in a jump table is 'special' (on this implementation) in the sense that it catch index out of bound, the first label is the 'error' label. If your code is bullet proof, i.e there is no way you can get an out of bound index, then the 1st label has not particular semantic.
CGOTO_dcl(gtb);
Declare the jump table 'gtb' own index as an auto integer so reentrant.
# define gtb(L) L(l0) L(l1) L(l2)
CGOTO_def(gtb);
Define a jump table named gtb, labels can be entered/removed with L(label) so it is pretty convenient, and this is symbolic by nature, i.e the labels are name with a meaning. With #define as a switch() case, labels addition/suppression often mean #define renumbering that is a problem.
The #define can be separated from the CGOTO_def() but it make more sense to keep them together. The CGOTO_def() though got to be placed after the function local declaration as it contain a switch() that is code.
A uniq jump table can be used in multiple place in the function.
CGOTO(gtb,x);
...
CGOTO(gtb,y);
A label may be entered in multiple jump table
# define gtb1(L) L(l0) L(l1) L(l2)
CGOTO_def(gtb1);
# define gtb2(L) L(l0) L(l4) L(l5)
CGOTO_def(gtb2);
So all in all, this may looks ugly, yet, the jump table definition though 2 line the #define and the CGOTO_def() is manageable and practical, semi performant, and portable.
We are back to FTN4 :)
Cheers,
Phi

Why is this construct used? Mad or genius?

I'm working with a large SDK codebase glommed together from various sources of varying quality / competence / sanity from Linus Torvalds to unidentified Elbonian code slaves.
There are an assortment of styles of code, some clearly better than others, and it's proving an interesting opportunity to expand my knowledge / despair for the future of humanity in alternate measures.
I've just come across a pile of functions which repeatedly use a slightly odd (to me) style, namely:
void do_thing(foo)
{
do {
if(this_works(foo) != success)
break;
return(yeah_cool);
} while (0);
return(failure_shame_death);
}
There's nothing complicated being done in this code (I haven't cut 10,000 lines of wizardry out for this post), they could just as easily do:
if(this_works(foo) == success)
return(yeah_cool);
else
return(failure_shame_death);
Which would seem somehow nicer / neater / more intuitive / easier to read.
So I'm now wondering if there is some (good) reason for doing it the other way, or is it just the way they always do it in the Elbonian Code Mines?
Edit: As per the "possible duplicate" links, this code is not pre-processed in any sort of macro, it is just in the normal code. I can believe it might be due to a coding style rule about error checking, as per this answer.
Another guess: maybe you didn't quote the original code correctly? I have seen the same pattern used by people who want to avoid goto: they use a do-while(0) loop which at the end returns a success value. They can also break out of the loop for the error handling:
int doXandY() {
do {
if (!x()) {
break;
}
if (!y()) {
break;
}
return 0;
} while( 0 );
/* Error handling code goes here. */
globalErrorFlag = 12345;
return -1;
}
In your example there's not much point to it because the loop is very short (i.e. just one error case) and the error handling code is just a return, but I suspect that in the real code it can be more complex.
Some people use the do{} while(0); construct with break; inside the loop to be compliant in some way with MISRA rule 14.7. This rule says that there can be only single enter and exit point in the function. This rule is also required by safety norm ISO26262. Please find an example function:
int32_t MODULE_some_function(bool first_condition,bool second_condition)
{
int32_t ret = -1 ;
do
{
if(first_condition)
{
ret = 0 ;
break ;
}
/* some code here */
if(second_condition)
{
ret = 0 ;
break ;
}
/* some code here */
} while(0) ;
return ret ;
}
Please note however that such a construct as I show above violates different MISRA rule which is rule 14.6. Writing such a code you are going to be compliant with one MISRA rule, and as far as I know people use such a construct as workaround against using multiple returns from function.
In my opinion practical usage of the do{}while(0); construct truely exist in the way you should construct some types of macros.Please check below question, it was very helpful for me :
Why use apparently meaningless do-while and if-else statements in macros?
It's worth notice also that in some cases do{}while(0); construct is going to be completely optimized away if you compile your code with proper optimization option.
Hm, the code might be preprocessed somehow. The do { } while(0) is a trick used in preprocessor macros; you can define them like this:
#define some_macro(a) do { whatever(); } while(0)
The advantage being that you can use them anywhere, because it is allowed to put a semicolon after the while(0), like in your code above.
The reason for this is that if you write
#define some_macro(a) { whatever(); }
if (some_condition)
some_macro(123);
else
printf("this can cause problems\n");
Since there is an extra semicolon before the else statement, this code is invalid. The do { ... } while(0) will work anywhere.
do {...} while(0) arranged with "break" is some kind of "RAII for Plain C".
Here, "break" is treated as abnormal scope exit (kind of "Plain C exceptions"), so you can be sure that there is only one place to deallocate a resource: after a "while(0)". It seems slightly unusual, but actually it's very common idiom in the world of plain C.
I would guess that this code was originally written with gotos for error handling:
void do_thing(foo)
{
if(this_works(foo) != success)
goto error;
return(yeah_cool);
error:
return(failure_shame_death);
}
But at some point an edict came down from on high "thou shalt not use goto", so someone did a semi-automatic translation from goto style to loop-break style (perhaps with simple script). Probably when the code was merged/moved from one project to another.

Personal Preprocessor Directives

Being a C novice I would like to hear what Macro "define"s developers are using. I've been thinking about putting these in a header to skip verbosity I've become used to:
#define TS_ typedef struct {
#define _TS(x) } x;
#define I(x)_ { int i; for ( i = 1; i <= x; i++ ) {
#define _I } }
Can I add \n \t etc within these macros? As I would like to pass on my sourcecode minus the extra include:
#define TS_ typedef struct {\n
#define _TS(x) } x;\n
#define I(x)_ { int i;\n\tfor ( i = 1; i <= x; i++ ) {\n
#define _I \t}\n}\n
Would these work?
ie: Can I use the proprocessor to replace my sourcecode with my personal include to formatted source without the include ?
Links to good preprocessor tips and tricks also appreciated.
Before you get started, do not use macro names that begin with an underscore - these are reserved for compiler and standard library writers, and must not be used in your own code.
Additionally, I would say that the macros you suggest are all very bad ideas, because they hide from the reader what is going on. The only justification for them seems to be to save you a very small amount of typing. Generally, you should only be using macros when there is no sensible alternative. In this case there is one - simply write the code.
You can put whitespace in by escaping the newline
#define SOMETHING whatever\
This is part of the macro
But as others have said it's not really a great way to to do this.
It would be much better to look into editor macros so you could type the shortcut and have the editor expand it.
You are headed into a wrong path. DO NOT make up your own cpp directives that are unfamiliar to others - this will make your code hard to understand, and at some point maintain.
Try to find some good C code to read - good C code does not use these things, for a good reason.
DON'T DO IT. Nobody else will be able to read your code.
As a cautionary example, check out Steve Bourne's original sources for the Bourne shell, where he used macros to write the code in a kind of pidgin Algol style.
You could do this, but this sort of "personal language" is not generally used in the C world, especially if you expect anybody else to read your code in the future.
If you're doing this just for yourself, then feel free to #define whatever you want, but expect that once you start working with (or for) anybody else, you won't be able to continue using this sort of thing.
Using C macros unnecessarily can lead you into a world of pain, especially if you attempt to use it to expand code. There are uses for C macros, but this is not it.
Edit: I realize that my answer is tangential to your question, but I thought I should mention this since you say you are a C novice. Search for "C macro pitfalls" to get a full list of reasons why not to use macros. It's been previously discussed here.
In general, I strongly agree with the other respondents who tell you not to define your own macros purely for the sake of saving typing. The obfuscation is not worth it. Also, the particular macros you suggest are heinous. However, in Stroustrup's 1st Ed, he does something I rather like (sometimes):
#define Kase break; case
I became accustomed to the Python elif construct, so I often define the following:
#define elif(test) else if(test)
My purpose in doing this isn't to reduce typing, it's to keep indentation logical while maintaining consistent code width (I don't let my code go wider than 80 characters). I say this because to me this...
if(...) ...
else if(...) ...
else ...
...should be...
if(...)
{
...
}
else
if(...)
{
...
}
else
{
...
}
With my macro this becomes:
if(...)
{
...
}
elif(...)
{
...
}
else
{
...
}
It is always better to pass the loop variable to the macro.
A block - a macro has certain optimization problems. All compilers do not guarantee an optimized obj code for the "block scope" variables.
for example, the following code, when compiled with out any optimization options to gcc, prints two separate addresses for &i. And the same code when compiled with -O2 option will print the same address in both the blocks.
{
int i;
printf("address of i in first block is %u\n", &i);
}
{
int i;
printf("address of i in sec block is %u\n", &i);
}
Naming the language constructs appropriately makes the code more readable.
I like your idea, if you put it in the following way.
#define GREEN 1
#define YELLOW 2
#define RED 3
# define NUM_COLORS 3
#define COLOR_ITER (color,i) \
for(i=GREEN, color = colors[i]; \
i < NUM_COLORS; \
color = colors[++i])
int colors[3] = {GREEN, YELLOW, RED};
int
fun () {
int j;
color_t clr;
COLOR_ITER(clr, j) {
paint(clr);
}
}
Here, regardless of how it is written, the macro, COLOR_ITER, by its name, implies that you are looping for all available colors and doing "something" for each color. And this is a very easy-to-use macro.
And your quesion
Can I use the proprocessor to replace my sourcecode with my personal include to formatted source without the include ?
As everybody explained preprocessor will not help you in this case.
You can use your editor commands to automatically format your code, as you type it.

Resources