2

Here is the code snippet:

#include <iostream>

int main()
{
    std::cout << std::hex << 123 << std::endl;

    std::cout << &std::hex << 123 << std::endl;
}
  1. What's &std::hex? I think it acquire the address of std::hex. And the address would be printed out.

  2. Is there any potential problem with this code snippet because somebody said it's bad to acquire the address of a function provided by the standard library?

John
  • 2,963
  • 11
  • 33
  • 1
    The question in my mind is why would you or what would motivate you to use `&std::hex` instead of just `std::hex` as is the normal usage in this context? – lurker Apr 10 '22 at 01:34
  • 3
    One reason questions are limited to one question each is to make tracking questions and answers simpler. In this case, your first question appears to be a duplicate of [Why do function pointer definitions work with any number of ampersands '&' or asterisks '*'?](https://stackoverflow.com/questions/6893285/) and your second a duplicate of [the question you linked to](https://stackoverflow.com/questions/55687044/) combined with [the list of designated addressable functions](https://en.cppreference.com/w/cpp/language/extending_std#Designated_addressable_functions), which contains `std::hex`. – JaMiT Apr 10 '22 at 01:59

1 Answers1

0

The name of a function decays into a pointer to that function. So std::cout << std::hex uses the stream inserter that takes a pointer to a function that takes an std::ios_base& and returns an std::ios_base&. The stream inserter simply calls the function.

Function pointers have another peculiar property: when you write &std::hex, it evaluates to the address of the function. Same for &&std::hex, &&&&std::hex, etc. They all mean the same thing.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • 1
    is the `$` a typo? I don't even think that `&&std::hex` is valid C++. So I'm not sure what you mean. – Wyck Apr 10 '22 at 01:16
  • Then what about the second question? – John Apr 10 '22 at 01:38
  • 1
    @John in this case, `std::hex` and other I/O manipulators are designated as *addressable functions*, so taking their address is allowed. See the "Addressing restriction" section @ https://en.cppreference.com/w/cpp/language/extending_std – Remy Lebeau Apr 10 '22 at 02:34
  • 2
    @Pete Becker `&&std::hex` do not compile! https://godbolt.org/z/shPhdsfx1 – John Apr 10 '22 at 04:13
  • 2
    I think you got it confused with `*****std::hex` with the implicit function-to-pointer conversion before every pointer indirect. `&&` in clang/gcc is parsed as a special "address-of-label" operator, and even `& &std::hex` doesn't work because it tries to take the address of the rvalue function pointer `&std::hex` – Artyer Apr 10 '22 at 08:05
  • @RemyLebeau What are the main differences between addressable functions and non-addressable functions? – John Apr 15 '22 at 01:17
  • @John the C++ standard does not allow you to take the memory address of non-addressable functions. – Remy Lebeau Apr 15 '22 at 01:25
  • @RemyLebeau Why? What are the benefits of not allowing to do so? – John Apr 15 '22 at 01:27
  • @John https://stackoverflow.com/a/66524080/65863 – Remy Lebeau Apr 15 '22 at 01:35
  • @RemyLebeau How to understand [`basic_ostream& operator<<(std::ios_base& (*func)(std::ios_base&) );` calls `func(*this)`](https://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt)? `std::cout<<&std::hex` is equivalent to `std::cout(std::hex)`? – John Apr 15 '22 at 01:55
  • @John `std::ios_base& (*func)(std::ios_base&)` is a pointer named `func`, that points to a function taking a `std::ios_base&` as a parameter and returning a `std::ios_base&`. This `operator<<` simply calls the pointed-at function, passing `*this` as the parameter. `&std::hex` takes the address of (returns a pointer to) the `hex` function. Referring to `std::hex` by just its name decays into a pointer to the `hex` function. Thus, `std::cout<<&std::hex` and `std::cout< – Remy Lebeau Apr 15 '22 at 09:16