29

So apparently C++20 is getting std::to_address.

From the cppreference page its use case doesn't seem clear to me. We already have operator& and std::addressof, why do we need yet another function that gives us an address to its argument?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
  • 12
    All these obscure and "only 0.1% of programmers will ever use this" functions are getting accepted and added into `std` but we still have no networking library for `std`, quite sad. – Hatted Rooster Jun 07 '19 at 11:48
  • [Notes](https://en.cppreference.com/w/cpp/memory/to_address#Notes) section provides an allocator example - `std::addressof` requires the object to be already constructed. – dewaffled Jun 07 '19 at 11:52
  • 1
    It's for C++ template metaprogramming, so both raw pointers and fancy pointers can be handled in the same way with `std::to_address`. – Eljay Jun 07 '19 at 11:52
  • @SombreroChicken the network library depends on the executors proposal which was not ready. Maybe in C++23 – KostasRim Jun 07 '19 at 11:55
  • 2
    @dewaffled I must've missed that. Basically just means it's yet another workaround function added to the standard to work around obscure standard rules that'd cause UB otherwise. Amazing. Cpp std is beginning to look like a circus – Hatted Rooster Jun 07 '19 at 11:55
  • 3
    http://www.stroustrup.com/P0977-remember-the-vasa.pdf – Evg Jun 07 '19 at 11:56
  • @Evg <3 for that paper. – KostasRim Jun 07 '19 at 11:57
  • @SombreroChicken: "*Basically just means it's yet another workaround function added to the standard to work around obscure standard rules that'd cause UB otherwise.*" Don't dereference null/invalid pointers is not an obscure rule. Or at least, it *shouldn't be*. – Nicol Bolas Jun 09 '19 at 21:48

1 Answers1

36

std::addressof takes an object and gets its address, even if unary "addressof operator" (aka &) was overloaded.

std::to_address takes a pointer, smart or dumb, and returns a pointer.

Basically when writing the std library, in this case allocators, implementors find they needed this utility function. It is small, simple, and has to be written whenever someone wants to work with allocators. So they wrote a no-brainer proposal to add it.

There are some traps here; you cannot do std::addressof(*ptr) because *ptr isn't always an object yet. There is already a trait that solves this, but writing code using traits directly is annoying.


Why this when they haven't finished your favourite feature? Like networking?

In comparison, networking is not a no-brainer proposal. And the current design depends on executors (basically abstractions of the concept of thread pools). The goal of writing a high level library that offers hand crafted C/ASM performance makes writing networking harder than a 2 line utility function.

Then somebody complains that they take 15 minutes to approve a no-brainer utility function, because the multiple programmer year epic proposal isn't in yet. The injustice.

Or something like that.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • 2
    It's really smart to call plain pointers dumb ... well, isn't it? – L. F. Jun 07 '19 at 12:19
  • Fair enough, I just don't understand why they need to add all these utilities that library writers want to use to `std`. Just add it to `std::we_are_cool_lib_writers` or something. – Hatted Rooster Jun 07 '19 at 12:35
  • 6
    @SombreroChicken The flip side is that if you *don't* specify that all these boring, implementation detail-ly, utility functions that are necessary to express `std::interesting_thing` as portable C++, people wanting to write `interesting_thing_with_important_difference` complain that they can't do what `std` does. E.g. `std::vector` needs some magic to create an array from a bunch of adjacent objects, and that can't be replicated in user code. – Caleth Jun 07 '19 at 13:09
  • Just to complement the line `*ptr isn't always an object yet` with an example: `int *p = new int{42}; int *wild_p = p + 10000000;`. `std::addressof(*wild_p)` dereferences `wild_p` in order to bind the object there to the parameter of `addressof`, causing immediate undefined behavior. While `std::toaddress(wild_p)` is perfectly valid. – SedriX Aug 27 '22 at 13:13