Usage of auto in JUCE code

i just can’t imagine that a variable that has to find out what it even is before starting to hold an actual value is good for the performance. any information about that? i mean we make audio plugins. things have to be super fast all the time

Are you talking about runtime performance? There will be no difference between using auto and explicit types. You can see this easily by looking at the assembled code on godbolt.org

2 Likes

Presumably doesn’t even give the compiler the sweats as previously it’d have needed to know the returned type anyway to check your code was valid…

2 Likes

On the contrary. The type deduction happens at compile time. And the auto might even avoid an implicit cast, if the type you told it to be was a different from the assigned type:

double getFoo() const;
auto foo = getFoo(); // no implicit cast
float bar = getFoo(); // implicit cast

auto baz = foo * bar; // there was little point to make bar a float
2 Likes

It’s been a while, but I feel I need to revert my critical stance and say something in favor of auto. Now that I got deeper into templates and meta-programing, I found that auto is totally indispensible. It keeps generic code lean (compile-time polymorphy) and has important uses for template deduction (e.g. where the return type of a function template is to be deduced). It is also great for lambda arguments, range-based loops and more.

That said, I don’t use it often for temporary variables, except for checking pointers in if-statements.

2 Likes

And now it’s been a further while… :slightly_smiling_face:

I’ve read this thread and get the idea behind auto and I have a quite simple beginner’s question on the use of the keyword in relation to casting. In the tutorial: Looping audio using the AudioSampleBuffer class, auto is used in a cast to float, index [3] below. Is this only a matter av convenience or are there any other benefits in this situation? To me it looks very strange to cast to auto.

 
            if (reader.get() != nullptr)
            {
                auto duration = (float) reader->lengthInSamples / reader->sampleRate;               // [3]
 
                if (duration < 2)
                {
                    fileBuffer.setSize ((int) reader->numChannels, (int) reader->lengthInSamples);  // [4]
                    reader->read (&fileBuffer,                                                      // [5]
                                  0,                                                                //  [5.1]
                                  (int) reader->lengthInSamples,                                    //  [5.2]
                                  0,                                                                //  [5.3]
                                  true,                                                             //  [5.4]
                                  true);                                                            //  [5.5]
                    position = 0;                                                                   // [6]
                    setAudioChannels (0, (int) reader->numChannels);                                // [7]
                }
                else
                {
                    // handle the error that the file is 2 seconds or longer..
                }
            }

The use of “auto” in that line indeed seems a bit odd, the writer of the code could have just used “float” instead to make it clearer what is going on.

The line isn’t really casting “into auto”, though. Both the variables in the division are integers, so to get a floating point result out of it, the first variable is cast to a float. The same thing would need to be done even if “auto” isn’t used.

This actually gets doubly confusing given that reader->sampleRate is a double, so duration will be a double too. You actually don’t need to cast reader->lengthInSamples at all and the result would be the same.

I’d say this is a case for using auto given that if you declared duration a float, you’d have lost some precision converting from double to float.

1 Like

Oh, that was an interesting twist. Seems like a mistake, but there’s a lot of casting in that section so maybe it just happened… :no_mouth:

Anyway, leaving that aside if indeed the variables would have been ints I was curious whether there is some performance or other actual benefit I miss of using auto, would these be identical in the compiled program in all cases:
auto x = (float) y
float x = (float) y

GodBolt is a useful tool for checking this sort of thing:

Short answer is yes, they’re identical. auto has no effect at runtime, it’s simply a way to ask the compiler to work out what type the variable needs to be, rather than figuring it out yourself.

1 Like

Great, thanks.

There is a semantic difference though.

auto duration = (float) reader->lengthInSamples / reader->sampleRate;

The result of the division is explicitly casted into a float.

The alternative:

float duration = reader->lengthInSamples / reader->sampleRate;

does an implicit cast to float during the assignment, which might light up a warning.

BTW. I prefer the modern cast (or even static_cast if I feel like being verbuous):

auto duration = float (reader->lengthInSamples / reader->sampleRate);

because I can see at first glance when the cast is happening, I am not even sure if the first version casts lengthInSamples or the result of the division.

reader->lengthInSamples is cast to a float, then divided by a double. So duration is a double, not a float.

In both other examples, you have a loss of precision (not that it’s needed here).

Yes, that was my hunch too, but I was too lazy to challenge the person using godbolt :wink:
Thanks for clarifying