What Is AudioDeviceManager::getAudioDeviceSetup() Actually Returning?

I am sure this is more of a C++11/C++14 question then a JUCE question.

juce::AudioDeviceManager *DeviceManager;
DeviceManager=new juce::AudioDeviceManager()

juce::AudioDeviceManager::AudioDeviceSetup *DeviceSetup;
DeviceSetup=new juce::AudioDeviceManager::AudioDeviceSetup()

I now want to make a copy of the contents of the currentSetup which is hanging off of
class JUCE_API AudioDeviceManager : public ChangeBroadcaster
{
AudioDeviceSetup currentSetup;
}

In order to get access to it, one should clearly utilize:
AudioDeviceManager::AudioDeviceSetup AudioDeviceManager::getAudioDeviceSetup() const
{
return currentSetup;
}

Being an old school C/C++ programmer, I am quite confused by this.
currentSetup is a struct.
AudioDeviceManager::AudioDeviceSetup AudioDeviceManager::getAudioDeviceSetup()
is returning the struct (which I have never seen before), not a pointer to the struct.

I am pretty sure this must be some sort of new C++11/C++14 type functionality that can only be understood by you youngsters! :slight_smile: To be honest I do not understand it!

memcpy(DeviceSetup,&(this->DeviceManager->getAudioDeviceSetup)(),sizeof(juce::AudioDeviceManager::AudioDeviceSetup));
seems to ‘work’ (meaning it does not crash), but still seems wrong to me. In addition the above statement produces a
‘warning C4238: nonstandard extension used: class rvalue used as lvalue’ (Visual Studio 2017)
I understand that I am taking an address of an rvalue, which is in fact bad.

I do understand that I could pick of each member of currentSetup and assign the value to my
DeviceSetup. I.e.:
DeviceSetup->outputDeviceName=(DeviceManager->getAudioDeviceSetup)().outputDeviceName;
for each member, but this does not seem wise as I am sure that at some point members could be added to the AudioDeviceSetup class / struct in future releases and I would never be aware of it.

So, again, I really do not understand what is actually being returned by
AudioDeviceManager::AudioDeviceSetup AudioDeviceManager::getAudioDeviceSetup()

I am hoping this does not sound like psychotic babble?

Thanks in advance for any direction.

I’m pretty sure that not only could C++98 return structs, but even C could do that in the 1980s!

auto setup = myAudioDeviceManager.getAudioDeviceSetup();

It’s as simple as that.

If you’re stuck in an old mindset of new/delete/memcpy/pointers then you’re just going to get yourself all tangled up and do silly stuff when you’re working with modern code - it’s worth taking the time to update your skills.

(And please use triple backticks to format code properly when posting!)

Thanks Jules.
Being an embedded programmer (ARM / Intel) in Southeastern Michigan (read as automotive industry) my inclination (it is inbred) is to attempt to minimize and optimize code for small footprint embedded devices. I will be the first to admit I am not up on ‘Modern’ techniques. This of course is not an excuse to start an argument seeing as me dev machine runs at 4.5Ghz with 32Gig of memory.

I guess I will go figure out how to create an auto variable on the heap!

Thanks.
Thanks.

Don’t create anything on the heap if you don’t actually need to. For example AudioDeviceManager::AudioDeviceSetup is just a simple data object which does not have polymorphic behavior, is not intended to be inherited from etc, so its size is always known and there is no need to allocate it dynamically on the heap.

2 Likes

auto is a nice feature, called type deduction. It is what you assign to it. I don’t think it is even possible to create an auto on the heap, but you can assign anything on the heap to it. The convention for the reader is here, to use the asterisk, even though it’s technically not necessary.

The main benefit for auto is, if you refactor your code, there won’t happen any unintentional implicit casts, and the other one, that auto can never be uninitialised. The compiler will fail in that case, because it cannot deduce any type.

Have a look at “almost always auto” by Herb Sutter