0

Consider the following code i managed to write:

#include <stdio.h>
#define FOR(A, B, C) for(A; B; C++)

int main()
{
    FOR(i=0, i<10, i)
    printf("%i", i);

    return 1;
}

The output is: 0123456789

If i do FOR(i=5, i<10, i) then respectively the output is 56789

My questions are is that legal? Will it cause any errors in different cases? Does it works exactly like a for loop?

Edenia
  • 2,312
  • 1
  • 16
  • 33
  • 2
    Why would you write macros like that? – Yu Hao Oct 17 '14 at 12:14
  • 1
    1. To use a common name for for loops instead of "for" 2. To save the writing of increment 3. To use the known function-form of parameters usage instead of for-form (using ; instead of commas) – Edenia Oct 17 '14 at 12:16
  • If that's your requirement, just write a function to do looping. You'll avoid the pit-falls of macros. – Ian Oct 17 '14 at 12:18
  • If i do function to do looping i will not be able to have a body of the for loop, which is a massive restriction. – Edenia Oct 17 '14 at 12:20
  • 6
    This is exactly that kind of preprocessor abuse that parents warn their kids about. Don't try to reinvent C with preprocessor, you will end up in maintenance nightmare. – user694733 Oct 17 '14 at 12:20
  • 1
    @Edenia You could use a callback. – Ian Oct 17 '14 at 12:21
  • Related: http://stackoverflow.com/q/652788/694733 – user694733 Oct 17 '14 at 12:28
  • @user694733 i would post this there if i knew it is that kind of "abuse" with preprocessor. For me.. it just more work for the preprocessor. – Edenia Oct 17 '14 at 12:31
  • @Ian what do you mean? – Edenia Oct 17 '14 at 12:42
  • @Edenia You could pass a function pointer into your standard for-loop function, the fp being a pointer to a custom function that's called to implement the job of the loop. See http://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work – Ian Oct 17 '14 at 12:49
  • @Ian oh with function pointers. I see. I have messed with that while working with signals before. – Edenia Oct 17 '14 at 12:51

2 Answers2

6

Yes it's a "legal" macro, but no, it does not work like a real for loop.

Your macro won't handle this:

int a, b;
for(a = 0, b = 4711; a < b; ++a);

for instance, since you can't distinguish the , used to build a longer initializing expression to the one used to separate the expressions that make up the parts:

FOR(a = 0, b = 0, a < b, ++a);

will break, since it looks like a call with 4 arguments instead of 3.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Well.. for that i could use the concatenation directive. – Edenia Oct 17 '14 at 12:18
  • 2
    You can use: FOR((a = 0, b = 0), a < b, ++a); – didou Oct 17 '14 at 12:29
  • 3
    @didou True, but kind of defeats the point in my opinion. Of course, "the point" for something horrible like this is a bit hard to see from the beginning. :) – unwind Oct 17 '14 at 12:29
  • This example also shows why this cannot work at all (no matter how the macro is defined). The example given is ambiguous as a macro and could also mean `for(a = 0; b = 0, a < b; ++a)`, for example. – mafso Oct 17 '14 at 12:52
2

A macro is just copied everywhere the preprocessor sees you using the macro keyword. It just copies the text, nothing more.

To elaborate on that a bit more, consider this example:

#define MY_MACRO a

int MY_MACRO = 5;

When the preprocessor comes along it will take the above and change it to:

int a = 5;

and then the compiler will come along and compile it like normal C/C++ code.

When you add arguments to your macro, they are just substituted in place within your macro. This can be a problem, consider the following two macros:

#define BAD_MACRO(a, b) a*b
#define GOOD_MACRO(a, b) (a)*(b)

They look almost the same, but consider the following:

int k = BAD_MACRO(2, 3);    // k = 2*3 = 6
int j = GOOD_MACRO(2, 3);   // j = 2*3 = 6
int m = BAD_MACRO(2+1, 3);  // m = 2+1*3 = 5
int n = GOOD_MACRO(2+1, 3); // n = (2+1)*3 = 9

Although note that neither of these macros are good or bad, they just don't have the same behaviour as a typical function.

ilent2
  • 5,171
  • 3
  • 21
  • 30
  • 1
    I fail to see how this is an answer to the question. Yes or no? – unwind Oct 17 '14 at 12:22
  • For me it looks like a decent lection of how macros work. And i have learn that it is better `#define SUM(A, B) ((A)+(B))` yes. But anyway thats not what i asked for. – Edenia Oct 17 '14 at 12:24
  • 1
    @unwind Yes, its legal; depends what you consider an error or a feature; and hmm, maybe but I don't think so... – ilent2 Oct 17 '14 at 12:25
  • Not quite what you asked for, but what I hoped you would find helpful. :) – ilent2 Oct 17 '14 at 12:26
  • I would really find it helpful. But i already know that.. so. – Edenia Oct 17 '14 at 12:27