5

I have a function which returns an integer value. Now I want to write a macro which call this function, gets the return value and prepends a string to it and return the resultant string.

I have tried this:

#define TEST(x)        is_enabled(x)

I call this macro in the main function as:

int ret = 0;
ret = TEST(2);
printf("PORT-%d\n", ret);

This works perfectly. However I want the macro to return the string PORT-x, where, x is the return value of the called function. How can I do this?

EDIT :

I also tried writing it into multiple lines as:

#define TEST(x)\
{\
    is_enabled(x);\
}

And called it in the main function as:

printf("PORT-%d\n", TEST(2));

But this gives a compile time error:

error: expected expression before â{â token
4
  • It can be done by writing a macro which "calls" sprintf, but you will need to allocate a buffer and pass it to that macro. The question is, why do you want this to begin with? Because it feels like you're trying to solve something in the wrong way. Commented Nov 25, 2014 at 7:12
  • Why can't you use strcat? Why is a macro required? Commented Nov 25, 2014 at 7:13
  • You should definitely write a function for this... Commented Nov 25, 2014 at 7:13
  • @Gopi I did not want to change the underlying function to return a string so I came up with an idea to modify the output of this function using a Macro. Is it so difficult? Commented Nov 25, 2014 at 7:16

2 Answers 2

5

Use a function, not a macro. There is no good reason to use a macro here.

You can solve it by using sprintf(3), in conjonction with malloc or a buffer. See Creating C formatted strings (not printing them) or man pages for details.

About your edit: You don't need to use braces {} in a macro, and they are causing your error as preprocessing would translate it to something like

printf("format%d", {
  is_enabled(x);
}); 

To better understand macros, run gcc or clang with -E flag, or try to read this article: http://en.wikipedia.org/wiki/C_preprocessor

Sign up to request clarification or add additional context in comments.

1 Comment

Finally, I implemented this in a function rather than writing a Macro.
2

That's a bit of a pain since you need to ensure there's storage for the string. In all honesty, macros nowadays could be reserved for conditional compilation only.

Constants are better done with enumerated types, and macro functions are generally better as inline functions (with the knowledge that inline is a suggestion to the compiler, not a demand).

If you insist on using a macro, the storage could be done with static storage though that has problems with threads if you're using them, and delayed/multiple use of the returned string.

You could also dynamically allocate the string but then you have to free it when done, and handle out-of-memory conditions.

Perhaps the easiest way is to demand the macro user provide their own storage, along the lines of:

#include <stdio.h>

#define TEST2_STR(b,p) (sprintf(b,"PORT-%d",p),b)

int main (void) {
    char buff[20];
    puts (TEST2_STR(buff, 42));

    return 0;
}

which outputs:

PORT-42

In case the macro seems a little confusing, it makes use of the comma operator, in which the expression (a, b) evaluates both a and b, and has a result of b.

In this case, it evaluates the sprintf (which populates the buffer) then "returns" the buffer. And, even if you think you've never seen that before, you're probably wrong:

for (i = 0, j = 9; i < 10; i++, j--)
    xyzzy[i] = plugh[j];

Despite most people thinking that's a feature of for, it's very much a different construct that can be used in many different places:

int i, j, k;
i = 7, j = 4, k = 42;

while (puts("Hello, world"),sleep(1),1);

(and so on).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.