jack-example-tools icon indicating copy to clipboard operation
jack-example-tools copied to clipboard

Fix portability issues with alloca()

Open 0EVSG opened this issue 4 years ago • 5 comments

As discussed on IRC: alloca() is a method to allocate dynamic memory on the stack. It is non-standard, although implemented on most platforms. In general it is superseded by the variable length array feature in C99.

The problem on FreeBSD is that there is no alloca.h header. Jack2 has an extra header in compat/alloca/alloca.h for systems where the alloca.h header is not present, specifically windows.

I can offer 3 ways to deal with this, thus 3 commits...

  1. Just remove the alloca.h includes. That may already be enough, because stdlib.h should include alloca() on platforms that implement it, and tools/netsource.c seems to be fine currently without the alloca.h include.
  2. Inline the Windows compatibility header from jack2, just to make sure we have no regressions.
  3. Replace all calls to alloca() with variable length arrays. Changes are rather trivial, but still more risky than 1. and 2.

0EVSG avatar Jan 08 '22 18:01 0EVSG

Let me figure out CI tests for windows for this repo, then we come back to this. Only yesterday I was finally able to find a way around github's updated image weirdness, but with that out of the way it should be quite straight forward now.

falkTX avatar Jan 08 '22 18:01 falkTX

BSD does not need alsa_in/out tools right? so we can skip changing those..?

falkTX avatar Jan 08 '22 18:01 falkTX

In general it is superseded by the variable length array feature in C99.

Except C99 does not mandate the memory to be allocated on the stack. This is compiler dependent, and memory may be on the heap (which is not realtime safe), while alloca() uses the stack so it can be used from rt-context.

x42 avatar Jan 08 '22 18:01 x42

Let me figure out CI tests for windows for this repo, then we come back to this.

That's a good idea, it's not an urgent issue.

BSD does not need alsa_in/out tools right? so we can skip changing those..?

I don't think anybody actively uses them, but we have the ALSA backend plus tools as a port option, so I can't be sure. I don't know the state of the FreeBSD ALSA compatibility layer (on top of OSS). Maybe I'd like to keep it in the build if it's not too much work.

Except C99 does not mandate the memory to be allocated on the stack. This is compiler dependent, and memory may be on the heap (which is not realtime safe), while alloca() uses the stack so it can be used from rt-context.

Thanks for the warning. I think we have to resort to compare actual implementations anyway, since there is no standard definition of alloca(). I'd be optimistic about that because allocation on the stack is the reason for its existence. Do you know a compiler that allocates VLAs on the heap?

That said, I'm not determined for changing to variable length arrays. We can skip that and just apply commit 1 or 1+2.

0EVSG avatar Jan 08 '22 19:01 0EVSG

In general it is superseded by the variable length array feature in C99.

Except C99 does not mandate the memory to be allocated on the stack. This is compiler dependent, and memory may be on the heap (which is not realtime safe), while alloca() uses the stack so it can be used from rt-context.

From my understanding, the C standard does not make any mention of stack or heap because that is seen as a platform-specific implementation detail for said platforms to worry about. From my understanding, variables that have "automatic storage duration" and are in a block scope, on most implementations will end up on the stack (assuming they aren't file scoped, external, static, or _Thread_local, which aren't allowed for VLAs, although they are allowed to be specified as register). In the examples of different types of VLAs, for int D[m]; it is described as being a VLA with automatic storage duration, as opposed to something like int (*s)[m]; which is described as being an automatic storage duration pointer to a VLA (which can point to the heap). Also, as mentioned earlier, VLAs cannot have external linkage, be in the file scope, be specified as static, or be specified as _Thread_local.

https://en.cppreference.com/w/c/language/array http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf (note: this is of C99TC3, but afaik, nothing related to VLAs was changed)

Also, looking up your claim online, this claim was on wikipedia at one point, but it was removed by Martin Uecker (who is a member of wg14): https://en.wikipedia.org/w/index.php?title=Variable-length_array&diff=818636913&oldid=818620350

If I am mistaken or misunderstanding something please correct me.

oreo639 avatar Jan 25 '22 22:01 oreo639

Rebased and stripped to only the first commit, skipping MSVC compatibility and VLAs as discussed on IRC.

0EVSG avatar Jan 29 '23 19:01 0EVSG

That is a really minimal diff, thanks!

falkTX avatar Jan 29 '23 19:01 falkTX