Is it safe to use juce::dsp::FixedSizeFunction?

Found the class in the API documentation and it is exactly what I need for what I’m currently woking on. Then I was irritated that it could not be found until I realised that it obviously has not been added to the public interface yet.

So, is it safe to use it? Probably I would have written something similar (maybe not sooo sophisticated – great work!) myself, but I don’t see the point in doing that if such functionality is already available with JUCE. What’s the reason that it has not been added to the public headers until now?

1 Like

That template didn’t exist until May of this year; it was only introduced to JUCE with version 6.0.0. But it was added to the public headers in the same commit that created it. So I don’t see any reason it wouldn’t be safe to use, assuming you can require a minimum version of JUCE > 6.0.0.

Yes and no. The class itself was added with that commit but it has not been included in the module header (which is the usual JUCE way of making something available to the public API) until now, see here https://github.com/juce-framework/JUCE/blob/b0c89174308a7eb2f6ad7c34617901ad4862d6e4/modules/juce_dsp/juce_dsp.h#L238

No FixedSizeFunction in there :man_shrugging:

1 Like

Ah, you’re right, my mistake. A #include "containers/juce_FixedSizeFunction.h" was added to the juce_dsp.cpp file on creation, but it wasn’t added to juce_dsp.h — and still isn’t there.

I agree, that’s confusing. :thinking:

Thanks. Originally we’d hoped to use FixedSizeFunction in some places other than the Convolution, just to give it a bit more testing before locking-in the interface.

Unfortunately we haven’t found any more places in JUCE to use it (yet!) so I’ve gone ahead and made it public now:

3 Likes

The comment says “creating a FixedSizeFunction instance will never allocate”, i was wondering is this is right?

Shouldn’t it be “assigning a function/lambda to a FixedSizeFunction will never allocate”?

The function’s buffer is stored directly inside the FixedSizeFunction (i.e. the sizeof (FixedSizeFunction<400, ...>) will be at least 400). I think this means that the current documentation is correct.

I only see placement new being used with the functions internal storage buffer so I wonder how this one should ever allocate?

yes, but why does this change anything?

Maybe this is a language misunderstanding, but “creating a … instance” is for me the synonym for creating the object wether on stack or on the heap. And when the memory is inside the FixedSizeFunction, more closely std::aligned_storage::type, it has to be allocated when creating the instance.

From the dsp::Convolution, i see that the queue which is holding the FixedSizeFunctions is created in advance. That makes sense.

can someone enlighten me, whats my thinking mistake ? :wink:

I think this means that an instance of a FixedSizeFunction won’t perform any allocation itself.

If you take a std::function, it can be created on the stack but calling it’s constructor with certain arguments (or assigning something to it afterwards) will lead to an immediate memory allocation triggered by the instance. FixedSizeFunction will guarantee you to never do that.

Thank you! I understand the working method exact like that.

But “FixedSizeFunction won’t perform any allocation itself.” is a big difference to “creating a FixedSizeFunction instance will never allocate”

So your point is that you could write e.g. auto myFunction = std::make_unique<FixedSizeFunction<100, void(int)>> and it would allocate heap memory?

In that case I think there is no single C++ type (besides maybe a completely empty struct) that could give you this guarantee – because if you decide to explicitly create an instance by allocating it on the heap it will always allocate. But creating a FixedSizeFunction as a stack variable – and I guess that is what it’s intended to be used like – won’t lead to heap allocation. Or do you mean something different?

Edit: re-read your post above and saw that you also mentioned stack memory allocation, sorry for overlooking that. But the I still come to the conclusion that this is basically the case for every C++ type, so talking about allocation in the context of a function in the namespace dsp makes it obvious for me that this is about heap memory allocation which is what most developers probably think of when you talk about allocation

We only worry about heap allocations, because they lock.

I only wanted to point out that the term “creating a FixedSizeFunction instance will never allocate” is completely miss-leading, especially for beginners. Maybe I’m looking at it too closely.

Well, strictly speaking you’re right but, as every object with size > 0 is allocated somewhere, allocation always means heap allocation in the context where this is relevant. Still, it could be better phrased as “will never allocate on the heap”.

2 Likes

Thanks, when you learning something new, trying to understand, these linguistic inaccuracies can often make life difficult.