424,948 Members | 816 Online
Need help? Post your question and get tips & solutions from a community of 424,948 IT Pros & Developers. It's quick & easy.

 P: n/a how to convert a program to a function/macro and put it in a header file? is there any shortcut method for this? thanks. Jun 12 '07 #1
34 Replies

 P: n/a Umesh said: how to convert a program to a function/macro and put it in a header file? Don't even try. Instead, find out how to use libraries. -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jun 12 '07 #2

 P: n/a On 12 Jun, 14:05, Richard Heathfield

 P: n/a How can I convert a function to a macro in general? e.g. void factorial(int n) { long int x=1; for (int i=1;i<=n;i++) x*=i; printf("Factorial of %d = %ld\n",n,x); } Jun 12 '07 #4

 P: n/a Umesh wrote: | How can I convert a function to a macro in general? e.g. | | void factorial(int n) | { | long int x=1; | for (int i=1;i<=n;i++) | x*=i; | printf("Factorial of %d = %ld\n",n,x); | } Sorry - there is no "general solution". Please re-read Richard's article. -- Morris Dovey DeSoto Solar DeSoto, Iowa USA http://www.iedu.com/DeSoto/ Jun 12 '07 #5

 P: n/a Umesh said: How can I convert a function to a macro in general? e.g. void factorial(int n) { long int x=1; for (int i=1;i<=n;i++) x*=i; printf("Factorial of %d = %ld\n",n,x); } You'd be better off asking "how can I avoid risking the generation of incorrect results?" -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jun 12 '07 #6

 P: n/a Richard Heathfield How can I convert a function to a macro in general? e.g.void factorial(int n){ long int x=1; for (int i=1;i<=n;i++) x*=i; printf("Factorial of %d = %ld\n",n,x);} You'd be better off asking "how can I avoid risking the generation of incorrect results?" He'd be *far* better off asking "How do I use this Usenet thing without looking like a parasite?". -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Jun 12 '07 #7

 P: n/a Umesh wrote: > How can I convert a function to a macro in general? e.g. void factorial(int n) { long int x=1; for (int i=1;i<=n;i++) x*=i; printf("Factorial of %d = %ld\n",n,x); } A function that declares local variables, is a poor candidate for conversion to a macro. /* BEGIN new.c */ #include #define factorial(N) \ do { \ n = N; \ x = i = 1; \ while (n >= i) { \ x *= i++; \ } \ printf("Factorial of %d = %ld\n", n, x); \ } while (0) void (factorial)(int n); int main(void) { long int x = 1, i = 1, n; factorial(5); (*factorial)(5); return 0; } void (factorial)(int n) { long int x = 1, i = 1; factorial(n); } /* END new.c */ -- pete Jun 12 '07 #8

 P: n/a // factorial by macro #include #define factorial(n) \ long int x=1; \ for(int i=1;i<=n;i++) \ x*=i; \ printf("Factorial of %d = %ld\n",n,x);\ main() { int n; printf("Enter No.- "); scanf("%d",&n); factorial(n); return 0; } Jun 13 '07 #9

 P: n/a Umesh said: // factorial by macro #include #define factorial(n) \ long int x=1; \ for(int i=1;i<=n;i++) \ x*=i; \ printf("Factorial of %d = %ld\n",n,x);\ main() { int n; printf("Enter No.- "); scanf("%d",&n); factorial(n); return 0; } foo.c:9: warning: return-type defaults to `int' foo.c:9: warning: function declaration isn't a prototype foo.c: In function `main': foo.c:13: parse error before `long' foo.c:13: parse error before `int' foo.c:13: `i' undeclared (first use in this function) foo.c:13: (Each undeclared identifier is reported only once foo.c:13: for each function it appears in.) foo.c:13: warning: statement with no effect foo.c:13: parse error before `)' foo.c:13: `x' undeclared (first use in this function) make: *** [foo.o] Error 1 -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jun 13 '07 #10

 P: n/a Richard Heathfield // factorial by macro#include#define factorial(n) \long int x=1; \for(int i=1;i<=n;i++) \x*=i; \printf("Factorial of %d = %ld\n",n,x);\main(){int n;printf("Enter No.- ");scanf("%d",&n);factorial(n);return 0;} foo.c:9: warning: return-type defaults to `int' foo.c:9: warning: function declaration isn't a prototype foo.c: In function `main': foo.c:13: parse error before `long' foo.c:13: parse error before `int' [snip] Umesh is obviously using a compiler that implements some C99 features. Using such features isn't wrong, merely non-portable. When I compile with "gcc -std=c99 -pedantic -Wall -W -O3", the only diagnostic I get is "warning: return type defaults to `int'". Of course, the program is horribly bad for other reasons. The use of a macro is entirely gratuitous, and the macro unaccountably prints the result rather than yielding it as a result. Here's another program that uses a macro to compute factorials: #include static unsigned long factorial_func(unsigned n) { unsigned long f = 1; unsigned i; for (i = 2; i <= n; i ++) { f *= i; } return f; } #define factorial(n) factorial_func(n) int main(void) { unsigned n; printf("Enter number: "); scanf("%u", &n); printf("factorial(%u) = %lu\n", n, factorial(n)); return 0; } The use of a macro is equally gratuitous, but at least this one operates more usefully. On a system with 32-bit longs, either program works only for arguments up to 12; using unsigned long rather than long didn't add enough range to change that. With 64-bit longs, it works for arguments up to 20. Neither version checks for overflow (which would be fairly difficult to do), but my version uses unsigned arithmetic and therefore avoids undefined behavior. The use of scanf for input is dangerous, as I've discussed here before, but I was too lazy to correct it. -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Jun 13 '07 #11

 P: n/a Which compiler do you use? It's working fine in TC++ 3/4.5 & VC++ 6 Jun 14 '07 #12

 P: n/a Umesh said: Which compiler do you use? When writing C programs, I am perfectly content to use *any* compiler that supports either ISO/IEC 9899:1990 when invoked in conforming mode or ISO/IEC 9899:1999 when invoked in conforming mode. It's working fine in TC++ 3/4.5 & VC++ 6 Neither of those compilers claims to conform to ISO/IEC 9899:1999. They do, however, claim to conform to ISO/IEC 9899:1990, so that's the standard by which programs written for them should be judged. By that standard, your program is invalid for the reasons stated. -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jun 14 '07 #13

 P: n/a WHICH COMPILER(S) DO YOU USE? GCC and other C compilers now support many of the new features of C99. However, there has been less support from vendors such as Microsoft and Borland that have mainly focused on C++, since C++ provides similar functionality improvement. GCC, despite its extensive C99 support, is still not a completely compliant implementation; several key features are missing or don't work correctly Richard Heathfield wrote: Umesh said: Which compiler do you use? When writing C programs, I am perfectly content to use *any* compiler that supports either ISO/IEC 9899:1990 when invoked in conforming mode or ISO/IEC 9899:1999 when invoked in conforming mode. It's working fine in TC++ 3/4.5 & VC++ 6 Neither of those compilers claims to conform to ISO/IEC 9899:1999. They do, however, claim to conform to ISO/IEC 9899:1990, so that's the standard by which programs written for them should be judged. By that standard, your program is invalid for the reasons stated. -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Jun 15 '07 #14

 P: n/a "Umesh" Richard Heathfield wrote: >Umesh said: Which compiler do you use? When writing C programs, I am perfectly content to use *any* compilerthat supports either ISO/IEC 9899:1990 when invoked in conforming modeor ISO/IEC 9899:1999 when invoked in conforming mode. It's working fine in TC++ 3/4.5 & VC++ 6 Neither of those compilers claims to conform to ISO/IEC 9899:1999. Theydo, however, claim to conform to ISO/IEC 9899:1990, so that's thestandard by which programs written for them should be judged. By thatstandard, your program is invalid for the reasons stated.--Richard Heathfield"Usenet is a strange place" - dmr 29/7/1999http://www.cpax.org.ukemail: rjh at the above domain, - www. Jun 15 '07 #15

 P: n/a "Keith Thompson" Umesh said: >>// factorial by macro#include#define factorial(n) \long int x=1; \for(int i=1;i<=n;i++) \x*=i; \printf("Factorial of %d = %ld\n",n,x);\main(){int n;printf("Enter No.- ");scanf("%d",&n);factorial(n);return 0;} foo.c:9: warning: return-type defaults to `int'foo.c:9: warning: function declaration isn't a prototypefoo.c: In function `main':foo.c:13: parse error before `long'foo.c:13: parse error before `int' [snip] Umesh is obviously using a compiler that implements some C99 features. Using such features isn't wrong, merely non-portable. When I compile with "gcc -std=c99 -pedantic -Wall -W -O3", the only diagnostic I get is "warning: return type defaults to `int'". Of course, the program is horribly bad for other reasons. The use of a macro is entirely gratuitous, and the macro unaccountably prints the result rather than yielding it as a result. Here's another program that uses a macro to compute factorials: #include static unsigned long factorial_func(unsigned n) { unsigned long f = 1; unsigned i; for (i = 2; i <= n; i ++) { f *= i; } return f; } #define factorial(n) factorial_func(n) int main(void) { unsigned n; printf("Enter number: "); scanf("%u", &n); printf("factorial(%u) = %lu\n", n, factorial(n)); return 0; } The use of a macro is equally gratuitous, but at least this one operates more usefully. On a system with 32-bit longs, either program works only for arguments up to 12; using unsigned long rather than long didn't add enough range to change that. With 64-bit longs, it works for arguments up to 20. Neither version checks for overflow (which would be fairly difficult to do) #include #include long factorial(int n) { long f = 1; int i; if (n < 0) { errno = EDOM; return n % 2 ? LONG_MIN : LONG_MAX; } for (i = 1; i <= n; i++) { if (f LONG_MAX / i) { errno = ERANGE; return LONG_MAX } else f *= i; } errno = 0; return f; } Fairly difficult? Jun 15 '07 #16

 P: n/a On Fri, 15 Jun 2007 17:33:40 +0200, in comp.lang.c , "Army1987" "Keith Thompson" >The use of a macro is equally gratuitous, but at least this oneoperates more usefully. .... >>Neither version checks for overflow(which would be fairly difficult to do) (snip code) >Fairly difficult? Remember, you're callling this via a macro. -- Mark McIntyre "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." --Brian Kernighan Jun 15 '07 #17

 P: n/a Keith Thompson Umesh said: >>// factorial by macro Of course, the program is horribly bad for other reasons. The use of a macro is entirely gratuitous, and the macro unaccountably prints the result rather than yielding it as a result. Here's another program that uses a macro to compute factorials: #include static unsigned long factorial_func(unsigned n) { unsigned long f = 1; unsigned i; for (i = 2; i <= n; i ++) { f *= i; } return f; } #define factorial(n) factorial_func(n) int main(void) { unsigned n; printf("Enter number: "); scanf("%u", &n); printf("factorial(%u) = %lu\n", n, factorial(n)); return 0; } The use of a macro is equally gratuitous, but at least this one operates more usefully. On a system with 32-bit longs, either program works only for arguments up to 12; using unsigned long rather than long didn't add enough range to change that. With 64-bit longs, it works for arguments up to 20. Neither version checks for overflow (which would be fairly difficult to do), It has just struck me that these two statements are at odds. If one really needed an absolutely cast-iron, overflow-safe factorial function, one would just use a look up table. Even in a future C with 256 bit integers, you'd only need 57 entries. It would have the added bonus of being quite fast. -- Ben. Jun 15 '07 #18

 P: n/a In article <87************@bsb.me.uk>, Ben Bacarisse If onereally needed an absolutely cast-iron, overflow-safe factorialfunction, one would just use a look up table. Even in a future C with256 bit integers, you'd only need 57 entries. It would have the addedbonus of being quite fast. Until you build it on a system whose int is 512 bit ;-) -- Programming is what happens while you're busy making other plans. Jun 15 '07 #19

 P: n/a LOOKS FINE BUT IF FAILS TO WORK FOR n>12 WHAT ABOUT USING LINKED LISTS? Army1987 wrote: #include #include long factorial(int n) { long f = 1; int i; if (n < 0) { errno = EDOM; return n % 2 ? LONG_MIN : LONG_MAX; } for (i = 1; i <= n; i++) { if (f LONG_MAX / i) { errno = ERANGE; return LONG_MAX } else f *= i; } errno = 0; return f; } Fairly difficult? Jun 15 '07 #20

 P: n/a Umesh . There's nothing wrong with quoting from outside sources, and the quoted material happens to be correct, but failing to provide attribution is rude and dishonest. -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Jun 15 '07 #21

 P: n/a Umesh 12 WHAT ABOUT USING LINKED LISTS? [...] Don't shout. (Writing in all-caps represents shouting.) Don't top-post. We've explained this to you numerous times; you've shown no evidence so far of being intelligent enough to understand it, but we're prepared to be pleasantly surprised. Be less obnoxious. -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Jun 15 '07 #22

 P: n/a Army1987 wrote: "Umesh" WHICH COMPILER(S) DO YOU USE?GCC and other C compilers now support many of the new featuresof C99. However, there has been less support from vendors suchas Microsoft and Borland that have mainly focused on C++, sinceC++ provides similar functionality improvement.GCC, despite its extensive C99 support, is still not a completelycompliant implementation; several key features are missing ordon't work correctly Well, I see that at least you know how to copy and paste. He also seems to have learnt the horrible habit of top-posting. Please do not top-post. Your answer belongs after (or intermixed with) the quoted material to which you reply, after snipping all irrelevant material. See the following links: --

 P: n/a "Army1987" Here's another program that uses a macro to compute factorials: [code snipped] >>The use of a macro is equally gratuitous, but at least this oneoperates more usefully. On a system with 32-bit longs, either programworks only for arguments up to 12; using unsigned long rather thanlong didn't add enough range to change that. With 64-bit longs, itworks for arguments up to 20. Neither version checks for overflow(which would be fairly difficult to do) #include #include long factorial(int n) { long f = 1; int i; if (n < 0) { errno = EDOM; return n % 2 ? LONG_MIN : LONG_MAX; } for (i = 1; i <= n; i++) { if (f LONG_MAX / i) { errno = ERANGE; return LONG_MAX } else f *= i; } errno = 0; return f; } Fairly difficult? Well, sufficiently difficult than I was unwilling to take the time to do it. -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Jun 15 '07 #24

 P: n/a ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes: In article <87************@bsb.me.uk>, Ben Bacarisse >If onereally needed an absolutely cast-iron, overflow-safe factorialfunction, one would just use a look up table. Even in a future C with256 bit integers, you'd only need 57 entries. It would have the addedbonus of being quite fast. Until you build it on a system whose int is 512 bit ;-) If you really need to compute factorials, chances are you'll need them for arguments that won't fit in any integer type, even if you have 512-bit integers. -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Jun 15 '07 #25

 P: n/a "Mark McIntyre" >"Keith Thompson" >>The use of a macro is equally gratuitous, but at least this oneoperates more usefully. ... >>>Neither version checks for overflow(which would be fairly difficult to do) (snip code) >>Fairly difficult? Remember, you're callling this via a macro. #include #define factorial(n) \ do { \ int n_ = n; \ long f = 1; \ int i; \ errno = 0; \ if (n_ < 0) \ printf("%d is negative, so it has no factorial\n", n_);\ else { \ for (i = 1; i <= n_; i++) { \ if (f LONG_MAX / i) { \ printf("%d is too large for its factorial "\ "to be computed\n", n_);\ errno = ERANGE; \ break; \ } \ else \ f *= i; \ } \ if (errno != ERANGE) \ printf("Factorial of %d is %ld\n", n_, f);\ } \ } while (0) /*I'm not saying that it doesn't suck...*/ Jun 15 '07 #26

 P: n/a "Walter Roberson" , Ben Bacarisse >If onereally needed an absolutely cast-iron, overflow-safe factorialfunction, one would just use a look up table. Even in a future C with256 bit integers, you'd only need 57 entries. It would have the addedbonus of being quite fast. Until you build it on a system whose int is 512 bit ;-) #include #include long factorial(int n) { static long table[13] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320L, 362880L, 3628800L, 39916800L, 479001600L }; int i; long f = table[12]; if (n < 0) { errno = EDOM; return n % 2 ? LONG_MIN : LONG_MAX; } if (n < 13) { errno = 0; return table[n]; } for (i = 13; i <= n; i++) { if (f LONG_MAX / i) { errno = ERANGE; return LONG_MAX; } else f *= i; } errno = 0; return f; } /*rewrite this eliminating multiple returns if you feel like it*/ Jun 15 '07 #27

 P: n/a "Keith Thompson" WHICH COMPILER(S) DO YOU USE?GCC and other C compilers now support many of the new features of C99.However, there has been less support from vendors such as Microsoftand Borland that have mainly focused on C++, since C++ providessimilar functionality improvement.GCC, despite its extensive C99 support, is still not a completelycompliant implementation; several key features are missing or don'twork correctly [...] The above two paragraphs are an uncredited direct quote from a Wikipedia article, . There's nothing wrong with quoting from outside sources, and the quoted material happens to be correct, and it happens to be relevant to the point, and the poster happens to understand why it is and what it means... but failing to provide attribution is rude and dishonest. Jun 15 '07 #28

 P: n/a Keith Thompson In article <87************@bsb.me.uk>,Ben Bacarisse >>If onereally needed an absolutely cast-iron, overflow-safe factorialfunction, one would just use a look up table. Even in a future C with256 bit integers, you'd only need 57 entries. It would have the addedbonus of being quite fast. Until you build it on a system whose int is 512 bit ;-) If you really need to compute factorials, chances are you'll need them for arguments that won't fit in any integer type, even if you have 512-bit integers. Sorry, I meant that the result, not the argumement, won't necessarily fit in any integer type. -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <* "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" Jun 15 '07 #29

 P: n/a On 15 Jun 2007 at 16:34, CBFalconer wrote: He also seems to have learnt the horrible habit of top-posting. Please do not top-post. Your answer belongs after (or intermixed with) the quoted material to which you reply, after snipping all irrelevant material. See the following links: --

 P: n/a On Fri, 15 Jun 2007 21:46:47 +0200, in comp.lang.c , "Army1987" "Mark McIntyre" Remember, you're callling this via a macro. #include #define factorial(n) \ (snip macro that could suck bowling balls through a drinking straw) >} while (0) /*I'm not saying that it doesn't suck...*/ *phew* -- Mark McIntyre "Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." --Brian Kernighan Jun 15 '07 #31

 P: n/a "Mark McIntyre" >"Mark McIntyre" >Remember, you're callling this via a macro. #include #define factorial(n) \ (snip macro that could suck bowling balls through a drinking straw) >>} while (0) /*I'm not saying that it doesn't suck...*/ *phew* Here is why I don't usually ever use the do { } while (0) trick. If I cannot write a macro that expands to an expression, not even abusing commas, &&s, ||s, ? :s and parentheses, then I write a function. (And if I cannot write a macro that does not evalue each argument exactly once, where each argument and the whole expression is surrounded by as many parentheses as possibly ever needed, which does not try to assign to or use the address of arguments etc., then I don't use lowercase in its name.) Here I wanted to show that writing a macro that writes the factorial of a number to stdout (other than #define PRINT_FACT(n) (printf("Factorial of %d is %ld," (n),\ factorial(n))) ) albeit possible, isn't worth the trouble. Jun 16 '07 #32

 P: n/a "Umesh" writes: Which compiler do you use? It's working fine in TC++ 3/4.5 & VC++ 6 Umesh, if you want to hold a conversation with someone via Usenet instead of E-mail, you and your correspondent should both post to alt.anonymous.messages, that's what the group is *for*. Doing so will avoid the need for the rest of us to be subjected to the fragmentary, disorganized thoughts you have from time to time. Do you understand that "you" refers to one particular person, and not a group of people collectively? Do you realize that you have not identified that person? Jun 16 '07 #33

 P: n/a In article <5d*************@mid.individual.net>, osmium Do you understand that "you" refers to one particular person, and not agroup of people collectively? Incorrect. "You" may be a single person, or it may be a group of people being addressed collectively, or it may be a generic "somebody" (though I believe that "one" is the english-pedant-correct word to use for that last one). dave -- Dave Vandervies dj******@csclub.uwaterloo.ca Wow, I actually I agree with you on some things. --Jesse Rodgers in uw.general Jun 16 '07 #34

 P: n/a On Sat, 16 Jun 2007 22:06:45 +0000 (UTC), dj******@csclub.uwaterloo.ca (Dave Vandervies) wrote: >In article <5d*************@mid.individual.net>,osmium >Do you understand that "you" refers to one particular person, and not agroup of people collectively? Incorrect. "You" may be a single person, or it may be a group ofpeople being addressed collectively, or it may be a generic "somebody"(though I believe that "one" is the english-pedant-correct word to usefor that last one). In formal usage you should use "one" but in informal usage one should use "you". Jun 16 '07 #35

### This discussion thread is closed

Replies have been disabled for this discussion.