Thread: loops and macros

  1. #1
    Registered User
    Join Date
    Jul 2009
    Posts
    23

    loops and macros

    Hi all,

    Is it possible to include a for or a while loop in a macro? I have an assignment that says to create a macro that will sum the elements of an array, but the book, obviously, didn't show any examples of loops in macros. And before you ask, yes I did read the FAQs, but there weren't any explanations for loops in macros either.

    Thanks again.

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by ginom71 View Post
    Hi all,

    Is it possible to include a for or a while loop in a macro?
    Yes.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Jul 2009
    Posts
    23
    What is the syntax? Do you write it like you would normally for a function prototype? This is what I have:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define SUMARRAY(x, y) \
    	(while(y!<0){\
    	(x[y]) + (x[y-1])\
    	y--)
    
    int main(void)
    {
    	int x[BUFSIZ];
    
    	fgets(x,BUFSIZ,stdin);
    
    	SUMARRAY(x, BUFSIZ);
    
    	system("pause");
    
    	return 0;
    }
    I keep getting a compile error that says "error C2059: syntax error : 'while'"

    If you can loop in a macro, what is the problem here?

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by ginom71 View Post
    What is the syntax?
    If you can loop in a macro, what is the problem here?
    Put in a normal block, using \ at the end of lines:

    Code:
    #define this(x) while(x>0) {printf("%d",x); \
           x--;}
    I'm not a big user of macros so I can't tell you what caveats may apply here, but I have seen macros do undesirable things when compared to an equivalent function sometimes esp when the caller is recursive, so watch for stuff like that.
    Last edited by MK27; 07-18-2009 at 10:11 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    Jul 2009
    Posts
    23
    Thanks again. I read that people have had trouble with recursive functions in macros. I'm not sure what the benefit is except for maybe simple computations.

    So I took your suggestion, and I wrote the following code:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define SUMARRAY(x,y) \
    	while(y > 0){\
    	x[y] + x[y-1];\
    	y--;}
    
    int main(void)
    {
    	int x[3] = {1, 2, 3};
    	int total;
    
    	total = SUMARRAY(x,3);
    
    	printf("%d", total);
    
    	system("pause");
    
    	return 0;
    }
    The problem is that I get 12 errors after I compile the code, and it starts with the same one "c_13.10.c(13) : error C2059: syntax error : 'while'". The question I have is that the first error points to line 13. Why is that?

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The problem is that I get 12 errors after I compile the code, and it starts with the same one "c_13.10.c(13) : error C2059: syntax error : 'while'". The question I have is that the first error points to line 13. Why is that?
    Remember that a preprocessor macro involves text substitution, so replace the macro use with the code that you defined the macro with and you will see the problem.

    As for a solution: have you learnt how to use pointers yet?

    EDIT:
    Oh wait, I just realised, since this is a macro, the use of a pointer as an out parameter is unnecessary. Anyway, the point is that you should use total as an argument to the function-style macro.
    Last edited by laserlight; 07-18-2009 at 10:33 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Jul 2009
    Posts
    23
    OK, so that while loop won't compile in the main body of the code. I wouldn't normally use that code to sum the elements in an array anyway. I'm just pretty lost when it comes to defining this in a macro.

    I have learned how to use pointers. That's not much different from using arrays.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by ginom71
    I'm just pretty lost when it comes to defining this in a macro.
    Basically, you need to pass three things to the function-style macro: the array name, the array size, and a variable to store the result. To loop, you need a loop counter, and this means defining a variable, hence you should use the do while loop trick, e.g.,
    Code:
    #define MY_MACRO(x) do\
    {\
        int i = 0;\
        /* ... */\
    } while (0)
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by ginom71 View Post
    Thanks again. I read that people have had trouble with recursive functions in macros. I'm not sure what the benefit is except for maybe simple computations.

    So I took your suggestion, and I wrote the following code:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define SUMARRAY(x,y) \
    	
    
    int main(void)
    {
    	int x[3] = {1, 2, 3};
    	int total;
    
    	total = SUMARRAY(x,3);
    
    	printf("%d", total);
    
    	system("pause");
    
    	return 0;
    }
    The problem is that I get 12 errors after I compile the code, and it starts with the same one "c_13.10.c(13) : error C2059: syntax error : 'while'". The question I have is that the first error points to line 13. Why is that?
    That's because the code expands to:
    Code:
    	total = while(3 > 0){
    	x[3] + x[3-1];\
    	3--;}
    The fact that this macro does not return the total is part of the problem, as laserlight points out. If you want the total, you have to add it as a parameter and assign the new value inside the macro.

    Then there's the problem that you are using the second parameter like a variable, but passing a constant.

    By the way, why are you using a macro anyway? Use a function. Always prefer a function to a macro when you can use either.
    Last edited by King Mir; 07-18-2009 at 11:11 AM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Just write the code as you normally would, make sure it compiles and works.
    Then take that code and make it into a macro, substituting certain parameters inside the code with parameters that the macro takes.
    It's very simple.
    But a friendly advice, though. Don't normally do this with macros; use functions instead. You only have to use macros here because the assignment demands it.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User
    Join Date
    Jul 2009
    Posts
    23
    OK, thanks everyone for the help. So you're saying that I need to write it out like I would for a function, which I did (just for practice). See below:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define SIZE 4
    
    int SUMARRAY(int y[], int size);
    
    int main(void)
    {
    	int x[] = {1, 2, 3, 4};
    	int sum;
    
    	sum = SUMARRAY(x, SIZE);
    
    	printf("%d\n", sum);
    
    	system("pause");
    
    	return 0;
    
    }
    int SUMARRAY(int y[], int size)
    {
    	int i;
    	int total = 0;
    
    	for(i = (SIZE - 1); i >= 0; i--){
    		total = total + y[i];
    	}
    	return total;
    }
    And what I thought all of you said was to write the function out like I normally would, so this is what I wrote:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define SUMARRAY(x, y) \
    	int i;\
    	int total = 0;\
    	for(i = (y - 1); i >= 0; i--){\
    		total = total + x[i];\
    	}\
    	return total;\
    }
    
    int main(void)
    {
    	int x[] = {1, 2, 3, 4};
    	int sum;
    
    	sum = SUMARRAY(x, 4);
    
    	printf("%d\n", sum);
    
    	system("pause");
    
    	return 0;
    
    }
    Only, I keep getting the same errors:
    c_13.10.c(17) : error C2059: syntax error : 'type'
    c_13.10.c(17) : error C2143: syntax error : missing ';' before 'type'
    c_13.10.c(17) : error C2065: 'i' : undeclared identifier
    c_13.10.c(17) : error C2065: 'i' : undeclared identifier
    c_13.10.c(17) : error C2065: 'i' : undeclared identifier
    c_13.10.c(17) : error C2065: 'total' : undeclared identifier
    c_13.10.c(17) : error C2065: 'total' : undeclared identifier
    c_13.10.c(17) : error C2065: 'i' : undeclared identifier
    c_13.10.c(17) : error C2065: 'total' : undeclared identifier
    c_13.10.c(19) : error C2143: syntax error : missing ')' before 'string'
    c_13.10.c(19) : error C2143: syntax error : missing '{' before 'string'
    c_13.10.c(19) : error C2059: syntax error : '<Unknown>'
    c_13.10.c(19) : error C2059: syntax error : ')'
    c_13.10.c(21) : error C2143: syntax error : missing ')' before 'string'
    c_13.10.c(21) : error C2143: syntax error : missing '{' before 'string'
    c_13.10.c(21) : error C2059: syntax error : '<Unknown>'
    c_13.10.c(21) : error C2059: syntax error : ')'
    c_13.10.c(23) : error C2059: syntax error : 'return'
    c_13.10.c(25) : error C2059: syntax error : '}

    Does this have something to do with the VB C++ compiler?
    Is it not possible to declare variables in a macro? If not, then I'm assuming that you declare them in the main body, and then pass them to the macro.

    So then I tried declaring the variables in the main body, like this:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #define SUMARRAY(x, y, z, t) \
    	for(z = (y - 1); z >= 0; z--){\
    	t = t + x[z];\
    	}\
    	return t;\
    }
    
    int main(void)
    {
    	int x[] = {1, 2, 3, 4};
    	int i = 0;
    	int total = 0;
    	int sum;
    
    	sum = SUMARRAY(x, 4, i, total);
    
    	printf("%d\n", sum);
    
    	system("pause");
    
    	return 0;
    
    }
    It still doesn't work.

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by ginom71
    And what I thought all of you said was to write the function out like I normally would, so this is what I wrote:
    No, I told you that you need to pass a variable to the macro to store the result. Consider this macro:
    Code:
    #define FOO(x) return (x);
    If you tried to use it as:
    Code:
    int a = 0;
    int b = FOO(a);
    it would actually be as if you wrote:
    Code:
    int a = 0;
    int b = return (a);
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Registered User
    Join Date
    Jul 2009
    Posts
    23
    Laserlight, thanks for you help. I removed the line:
    Code:
    sum = SUMARRAY(x, 4, i, total);
    and replaced it with;
    Code:
    SUMARRAY(x, 4, i, total);
    That cleared everything up, is that because I already had a return value?

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by ginom71
    That cleared everything up, is that because I already had a return value?
    More like because function-style macros are not functions, they do not have return values in the way that functions do.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed