22

I have a C++ program in which I want to insert default values for any keys missing in a std::map. I'm thinking the easiest way to do this would be to use std::map::operator[]() like the POSIX touch command - that is, to leave the value unchanged if it already exists, but to create it if it doesn't. For example,

#include <map>
#include <vector>
#include <iostream>

using namespace std;

int main()
{
    vector<int> keys = {0, 1};

    map<int, int> m;
    m[1] = 5;
    m[2] = 12;

    for (const int i : keys)
    {
        m[i]; // touch value
    }

    for (auto const & kv : m)
    {
        cout << kv.first << ", " << kv.second << endl;
    }
}

Can I be sure that the compiler won't optimize out the m[i]; statements, since I'm not "doing" anything with them? (Not explicitly assigning to, not reading from.)

cp.engr
  • 2,291
  • 4
  • 28
  • 42

3 Answers3

17

Yes you can be sure. Optimizing the call away would change the observable behavior of your program, and the compiler is not allowed to do this (except in the case of RVO).

This is known as the as-if rule.

Community
  • 1
  • 1
Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • Can you cite a source? – cp.engr Oct 12 '15 at 21:43
  • Thanks. May I suggest quoting this bit in your answer? "an actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no side effects affecting the observable behavior of the program are produced." From the second blockquote in the accepted answer you linked. – cp.engr Oct 12 '15 at 21:51
  • 1
    @cp.engr To be honest, I feel like the link to the other question that explains the matter very well is better than copying some incomplete part of the answer over here. Especially since this is an on-site resource and thus very safe from link decay. – Baum mit Augen Oct 12 '15 at 21:55
  • I just thought it was the most pertinent bit, given the question I asked. Of course the link should still stay. – cp.engr Oct 12 '15 at 21:57
  • 2
    @cp.engr I still do not feel good about quoting this here. For one, this does not even touch on what "observable behavior" is in the first place. Then, the section is only an "explanatory footnote". And last but not least, we already have a good explanation of the as-if rule on this site which I can refer to. That fits with the spirit of not duplicating answers; if for instance the standard wording was to change in some detail, we would only have to edit that one post instead of going on a scavenger hunt. TL;DR: The quote would be too incomplete to make this worth it IMO. – Baum mit Augen Oct 12 '15 at 22:03
6

Yes, you can be sure. It's perhaps more intuitive when you consider that the line in question is equivalent to this:

m.operator[](i);

…and you don't expect arbitrary function calls to be optimised out of your program, if they do anything.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
5

The [] operator does indeed default-construct the value that would be at that key's location if you do not assign it something.

Reference Link

If k does not match the key of any element in the container, the function inserts a new element with that key and returns a reference to its mapped value. Notice that this always increases the container size by one, even if no mapped value is assigned to the element (the element is constructed using its default constructor).

Connor Hollis
  • 1,115
  • 1
  • 7
  • 13