1

I am trying to port a C (not C++) program from GCC to Visual Studio.

The GCC specific function strdupa() is widely used in this program. Is there any way to implement this function for Visual C.

PS. I understand that it uses alloca() and it is unsafe. But it works very well on GCC now and I think it is safer to implement the same function in one place then change the logic of program. I also don't want performance to decrease.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
Sandro
  • 2,707
  • 2
  • 20
  • 30
  • Well, according to [the documentation](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/alloca?view=vs-2019), there is a function equivalent to `alloca()`, which you could use to implement your own `strdupa()`. However, it is marked as deprecated and the suggested replacement doesn't behave in the same way (it might allocate on the stack or on the heap, and therefore requires calling a free function, so it is not a drop-in replacement) – Felix G Jul 22 '20 at 10:56
  • 1
    @FelixG I understand that visual c has its own equivalent of alloca, but how to implement strdupa()? How to avoid freeing of memory when I return from my own implementation of strdupa()? – Sandro Jul 22 '20 at 11:04
  • 2
    I suggest to create a macro. The macro can allocate space on local stack. It should work as an inline function (that should be the case also for `strdupa` to use local stack). – Frankie_C Jul 22 '20 at 11:26

2 Answers2

3

I'd implement it as a macro:

#define strdupa(a) strcpy((char*)alloca(strlen(a) + 1), a)

That way it is not in a function and so the alloca'd string won't be freed prematurely.


Note: From man:

On many systems alloca() cannot be used inside the list of arguments of a function call, because the stack space reserved by alloca() would appear on the stack in the middle of the space for the function arguments.

… i.e. (from "GNU C Library Reference Manual"):

Do not use alloca inside the arguments of a function call—you will get unpredictable results, … . An example of what to avoid is foo(x, alloca(4), y).

Community
  • 1
  • 1
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • Yes, I think this is the solution. I will use it! But I am just curious, if there any way to implement it as function? – Sandro Jul 22 '20 at 11:29
  • @Sandro yes you could do that, but that implies a lot of platform specific stuff including assembly code. Look at the source code of `alloca` which is available somewhere in the Windows SDK installed on your computer. – Jabberwocky Jul 22 '20 at 11:31
  • 1
    @Sandro also interesting information: https://stackoverflow.com/a/33728005/898348 – Jabberwocky Jul 22 '20 at 11:34
0

My way to implement it as function. Not sure that it is safe, but it seems it works:

__forceinline char* strdupa(const char* s) {
    return strcpy((char*)_alloca(strlen(s) + 1), s);
}

But I think macro it a better way than using __forceinline

Sandro
  • 2,707
  • 2
  • 20
  • 30