Fix portability issues with alloca()
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...
- Just remove the
alloca.hincludes. That may already be enough, becausestdlib.hshould includealloca()on platforms that implement it, andtools/netsource.cseems to be fine currently without thealloca.hinclude. - Inline the Windows compatibility header from jack2, just to make sure we have no regressions.
- Replace all calls to
alloca()with variable length arrays. Changes are rather trivial, but still more risky than 1. and 2.
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.
BSD does not need alsa_in/out tools right? so we can skip changing those..?
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.
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.
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.
Rebased and stripped to only the first commit, skipping MSVC compatibility and VLAs as discussed on IRC.
That is a really minimal diff, thanks!