0

I have a macro defined as following:

#define MAP_ACTUAL(input) do {\
    char testPath[256];\
    getcwd(testPath, sizeof(testPath));\
    strcat(testPath, "/actual");\
    strcat(testPath, input);\
    input = testPath;\
} while(0)

And it works as intended when I use it once. When I use it twice in the same function like this:

static int do_rename(const char *from, const char *to) {
    printf("[rename] %s -> %s\n", from, to);
    MAP_ACTUAL(from);
    MAP_ACTUAL(to);
    // rest of the function
}

The values from and to point to the same address, I'm guessing to testPath, resulting in both of them having the same value (not intended). I was under the impression that since macro was defined in a do while scope it should use a separate address. How can I fix this?

I'm using gcc 8.2.1.

user_4685247
  • 2,878
  • 2
  • 17
  • 43
  • No, it does not work. Your code has undefined behaviour even in that case. Have two path arrays, giving the array as a macro argument, defined at the top-level, or even better, use `malloc` to allocate to the actual size. – Antti Haapala -- Слава Україні Mar 10 '19 at 19:24
  • `input = testPath;` - `testPath` stops existing after `} while(0)`. The pointer is invalid. – KamilCuk Mar 10 '19 at 19:26
  • For the record, one way to fix your problem would be to use `alloca` to allocate your buffer in the local stack frame. Beware of using `alloca` together with variable-length arrays, however; some compilers (or versions of compilers) do not play nice with that combination. – Dolda2000 Mar 10 '19 at 19:28
  • @Dolda2000 thanks! I didn't know about alloca, this solved my problem, mind posting this as the answer, so I can accept it? – user_4685247 Mar 10 '19 at 19:33
  • @tofiffe: Since the answer is marked as duplicate, I can't post answers. – Dolda2000 Mar 10 '19 at 19:38
  • Note that `alloca` is not standard in any way. Also, using preprosessor macros in this way is generally considered a bad idea, and your very question is one example why this is so. Then, to debug macros like this, expand them by hand, that often makes it clear what the problem is (a problem, which you wouldn't have in the first place if you used for example normal functions). – hyde Mar 10 '19 at 20:13
  • so I take it the recommended way would be to use a function and use malloc in it then free once I was done using that memory? My goal was just to prepend some string, without needing to free memory later on, alloca seems to be doing exactly that. I only work with C in my free time, other languages usually allocate a separate array for new scope, which is what I expected to happen here. – user_4685247 Mar 10 '19 at 20:20
  • String manipulation functions often take all buffers from caller as parameters. C is not garbage collected, things have definite lifetimes. Also you should use functions which can't produce buffer overflow, such as `strncat` here, or maybe just `snprintf`. – hyde Mar 11 '19 at 05:42

0 Answers0