Quick sanity check on some code

Hi everyone,

I’ve gotten into the habit of returning std::pair from functions that should return stereo output values. Here’s an example that sums output from a few different “tracks” of audio:

    float left_output = 0;
    float right_output = 0;
    float track_left_output;
    float track_right_output;

    for(unsigned int i = 0; i < NUMBER_OF_TRACKS; i++)
    {
      std::tie(track_left_output, track_right_output) = selected_pattern->tracks[i].getStereoOutput();
      left_output += track_left_output;
      right_output += track_right_output;
      selected_pattern->tracks[i].incrementSamplePosition(args.sampleRate);
    }

    // Output voltages at stereo outputs
    outputs[AUDIO_OUTPUT_LEFT].setVoltage(left_output);
    outputs[AUDIO_OUTPUT_RIGHT].setVoltage(right_output);

The function getStereoOutput() returns std::pair<float, float>

Is this good practice, or should I send in references to track_left_output and track_right_output (such as &track_left_output) and populate those variables within the function?

Thanks!
Bret

Not sure Compiler Explorer, Compiler Explorer

1 Like

In my experience, the compiler will usually generate the exact same assembly regardless of which approach you use, (like in this Compiler Explorer with clang 14). That said, I would imagine there’s some specific cases where std::pair (or std::tuple) might give some performance improvement by being able to “pack” the values in the pair together, similar to “negative-cost structs”.

One thing to watch out for is that you probably don’t want to return a std::pair of objects that are more complicated than a simple stack variable like float, int, etc., since there might be a move or copy operation associated which would need to happen. Like, things get way more complicated if we repeat the above Compiler Explorer example, using std::complex<long double> instead of float.

4 Likes

Ah! This is my first time hearing of Compiler Explorer. How cool! Thanks!