views:

231

answers:

9

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.

+15  A: 

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 ver 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.

anon
+1  A: 

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.

Greg Hewgill
@Greg: That exactly why I'm asking whether I can use the use the preprocessor to create source which I can then pass on. Did you read past the first codeblock ?
_ande_turner_
I did indeed. I didn't quite understand what you meant by "pass on". Note that not only is running the preprocessor going to replace *your* macros, but it is also going to replace all other macros declared and used in your code. You can't ask it to apply only a specific subset of macros.
Greg Hewgill
Anyway, giving people C code that has already been run through the preprocessor could be considered obfuscation. Nobody does this.
Greg Hewgill
And the result of putting *your* system's includes into a source file inherently makes the output of your C preprocessor non-portable.
Charles Bailey
+1  A: 

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.

nagul
+5  A: 

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.

Eli Bendersky
+6  A: 

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.

John Burton
@JB: Yep editor macros are definitely the way to go here. :D
_ande_turner_
A: 

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
William Pursell
A: 

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
{
    ...
}
Imagist
Why not just say "else if(test)" (on one line)?
anon
A: 

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.

mallik
+2  A: 

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.

Norman Ramsey