2

Are there any side effects / problems that could arise in doing someMap.insert(make_pair(nullptr, nullptr))? Not including the dangers of dereferencing the null pointer.

Momo
  • 318
  • 2
  • 11
  • 1
    If you use a pointer type as key of a map then `nullptr` is a valid value for this key. Problems may arise when you use the key (e.g. in iteration) for derefencing (i.e. access to contents) without checking. But that's a general issue with pointers, isn't it? In case of the unordered map, it depends on the hash function. If the hash function just uses the numerical value of the pointer - no problem. (I strongly believe that's the default for pointer hashing.) But if you use a customized version which dereferences the pointer... - see above. – Scheff's Cat Jan 05 '20 at 09:55
  • FYI: [SO: Hashing pointers as Keys for unordered_map in C++ STL](https://stackoverflow.com/q/25124923/7478597) – Scheff's Cat Jan 05 '20 at 10:02
  • @Peter - What non-pointer types? – StoryTeller - Unslander Monica Jan 05 '20 at 10:04
  • `nullptr` is incompatible with non-pointer types. That's it's whole purpose. – rustyx Jan 05 '20 at 10:49
  • What is `someMap`? Is the key `std::nullptr_t` or something else? – Lightness Races in Orbit Jan 05 '20 at 18:36
  • @LightnessRacesBY-SA3.0 I left it ambiguous to get creative answers from people's assumptions, but if you want to know it was originally `` in my code. – Momo Jan 05 '20 at 22:07
  • @Momo It's important because `` would yield completely different answers. Please always ensure that you give the full context. You never know what the details might mean. That's why you're asking, right? :) Save us from having to chase for the details; just give them up-front. Easier for everybody. – Lightness Races in Orbit Jan 06 '20 at 00:34
  • @LightnessRacesBY-SA3.0 Got it! – Momo Jan 06 '20 at 02:18

3 Answers3

2

The validity of this is entirely dependent on what exactly someMap is.

Let's assume someMap has a key-type which is an actual pointer (that is, not a pointer-like type, but a T* of some kind).

Then the question becomes what the validity is of comparing two pointers if one of them is nullptr. Which means asking... how does the map compare its key type?

std::map's key comparison is configurable. By default, it uses std::less<Key>.

This is important because normal ordering comparison of pointers using < or whatever only imposes a partial ordering between pointer values. Pointers within the same array can be compared, as well as pointers to subobjects within the same object (ordered by declaration, for standard-layout types). Therefore, order-comparisons between a null pointer and any pointer value other than another null pointer is not permitted.

Fortunately for you, std::less has a specialization for pointers which imposes a total order to all pointer values. by contrast defines a total order for all pointers.

However, if you have provided a different comparison type, one which is based on invoking < rather than std::less, then you cannot insert nullptr into such a map.

If the key-type is some kind of pointer-like type, one which does comparisons based on the value of the pointer, then again, it had better be using std::less instead of <, or you're in trouble.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
1

There is no violations in someMap.insert(make_pair(nullptr, nullptr)). But you need to pay attention when use this element to not dereference the nullptr or your program will have undefined behaviour (and may trigger a Segmentation Fault).

Note: Obviously the map need to have a pointer in the key and a pointer in the value, or the expression can cause a compile error or in the worst case an Undefined Behaviour.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Zig Razor
  • 3,381
  • 2
  • 15
  • 35
1

This is fine.

A null pointer is a valid value for a pointer to hold. You can do anything with it that you can do with any other valid pointer, (except dereference it).

Do make sure that you pointers are valid. If they are not, merely evaluating them has undefined behaviour (implementation-defined behaviour since C++17). But evaluating a null pointer is fine because it's not "invalid", just undereferencable.

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