-2

I have a following code:

#include <iostream>
#include <unordered_map>
#include <string>

int main()
{
  std::unordered_map<std::string, int> map;
  std::cout << map["foo"]; // -> 0

  return 0;
}

I am using map["foo"] without initialisation. Is this code valid or UB?

Edit: I tried to compile in godbolt and got 0 output with clang and gcc (trunk version) https://godbolt.org/z/KeWq7nbob.

mouse_00
  • 593
  • 3
  • 13
  • 2
    Does this answer your question? [map default values](https://stackoverflow.com/questions/2667355/mapint-int-default-values). Also [std::map default value for build-in type](https://stackoverflow.com/q/4523959/11082165) – Brian61354270 Jul 18 '23 at 15:23
  • you need to read some docs https://en.cppreference.com/w/cpp/container/map/operator_at – 463035818_is_not_an_ai Jul 18 '23 at 15:24
  • It's valid. I'm not sure exactly what you think is uninitialized in this code. `map` is initialized, and so is the map entry you added using the `[]` operator. – john Jul 18 '23 at 15:24
  • 1
    @john: `int`s default constructor is "uninitialized". The confusion is caused by the assumption that the map "default constructs" the `int`. Which is a fair confusion to have, because many people incorrectly say that maps default initialize values. – Mooing Duck Jul 18 '23 at 15:25
  • I wouldn't say that C++ reference page is clear about what sort of initialization happens when the key is "inserted". This sort of question is a good one to have on SO. It just happens to be a duplicate – Brian61354270 Jul 18 '23 at 15:29

1 Answers1

2

When operator[] does not find the value with given key one is inserted into the map. From cppreference:

Inserts value_type(key, T()) if the key does not exist. [...]

T() is Zero-initialization. For int this bullet applies:

If T is a scalar type, the object is initialized to the value obtained by explicitly converting the integer literal ​0​ (zero) to T.

All is fine in your code. map["foo"] returns a reference to 0 after inserting that 0 together with the key constructed from the string literal "foo" into the map. This is the intended use of std::map::operator[]. If you want to check if an element exists in the map use std::map::find. If you want to find an existing one or insert if none is present, use std::map::insert.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185