Incorporate __PRETTY_FUNCTION__ into the C++ standard

4,052 views
Skip to first unread message

ant...@perezexcelsior.com

unread,
Nov 1, 2016, 2:01:38 AM11/1/16
to ISO C++ Standard - Future Proposals
Currently, __func__ is part of the c++ standard, however __PRETTY_FUNCTION__ (part of GCC and Clang) provides significantly more information about a function. It's more useful for printing debugging information and error messages, and in addition it provides a method for getting the programmatic name of a type. An example usage is shown below:

#include <string>
#include <iostream>
#include <tuple>

template<class type> constexpr std::string GetName()
{
const char* start = __PRETTY_FUNCTION__;
while(*start != '=') ++start;
start += 2;
size_t size = 0;
while(start[size] != ';') ++size;
return std::string(start, size);
}
int main()
{
std::cout << GetName<void>() << std::endl; 
std::cout << GetName<int>() << std::endl;
std::cout << GetName<decltype(0.3)>() << std::endl;
std::cout << GetName<std::tuple<int, char>>() << std::endl;
// Output: 
// void
// int
// double
// std::tuple<int, char>
}


D. B.

unread,
Nov 1, 2016, 3:39:40 AM11/1/16
to std-pr...@isocpp.org
it provides a method for getting the programmatic name of a type

So does typeid().name() if you're willing to decode it. My guess is you don't think that's "PRETTY" enough.

What's your proposed format for the result of this macro? That might help people get enthused.

However, I don't think I can, since this is nothing I can't already do myself while debugging - a process that can never be pretty anyway - and anyway, I would prefer a macro to get the pretty name of a single designated type, rather than having to chop it out of a (currently arbitrary) string myself.
 

Jonathan Müller

unread,
Nov 1, 2016, 4:10:25 AM11/1/16
to std-pr...@isocpp.org
On 01.11.2016 08:39, D. B. wrote:
>I would prefer a macro to get the pretty name of a single
> designated type, rather than having to chop it out of a (currently
> arbitrary) string myself.

There is a `typename(type)` that returns a string proposed by some
reflection proposal, isn't it?

D. B.

unread,
Nov 1, 2016, 6:33:46 AM11/1/16
to std-pr...@isocpp.org
On Tue, Nov 1, 2016 at 8:10 AM, Jonathan Müller <jonathanm...@gmail.com> wrote:

There is a `typename(type)` that returns a string proposed by some reflection proposal, isn't it?

Yeah, no doubt all reflection proposals have a solution for this, and in a much tidier way, so the 'get a type name' argument doesn't hold water to me. Done right, reflection would also better serve the 'get a function signature' use case. I think it's more productive to push for reflection to be standardised, as it just keeps coming up, and it could solve this as a consequence. Getting a modular reflection system in seems more productive than arguing about exactly how a debug text string should be formatted (to the level of arguing over the positioning of asterisks, ampersands, etc.)

Maybe I'm wrong and there's some key feature of __PRETTY_FUNCTION__ that makes it uniquely desirable, which I might see if the OP would actually substantiate the proposal and its context, instead of just asking for it to be added.

Arthur O'Dwyer

unread,
Nov 1, 2016, 7:09:06 PM11/1/16
to ISO C++ Standard - Future Proposals, ant...@perezexcelsior.com
On Monday, October 31, 2016 at 11:01:38 PM UTC-7, ant...@perezexcelsior.com wrote:
Currently, __func__ is part of the c++ standard, however __PRETTY_FUNCTION__ (part of GCC and Clang) provides significantly more information about a function.

FWIW, my attitude toward __PRETTY_FUNCTION__ is the same as my attitude toward "#pragma once" (in the recent thread on that subject).  I love it and evangelize its usage; but since it already exists and works great (for me and everyone I know), what's the benefit of standardizing it?  Just to antagonize the MSVC dev team? ;)  (MSVC supports something called _FUNCSIG but not __PRETTY_FUNCTION__. I'd love for them to get on that, but I don't think the ISO C++ committee is the right vector for MSVC feature requests.)

Putting on my language-lawyer hat: Notice that there is technically nothing stopping any vendor from making __func__'s implementation-defined string match the output of GCC's __PRETTY_FUNCTION__.  Also notice that __FUNCTION__ itself is not yet standardized; __func__ was C99's way of sneaking __FUNCTION__-like semantics into the language without having to admit the existence of predefined macros.

IMHO you have presented a very neat little GetName() idiom that works on all implementations I care about; but IMHO you have not particularly shown any reason for changing the C++ Standard.

my $.02,
–Arthur

Nicol Bolas

unread,
Nov 1, 2016, 9:02:04 PM11/1/16
to ISO C++ Standard - Future Proposals, ant...@perezexcelsior.com
On Tuesday, November 1, 2016 at 7:09:06 PM UTC-4, Arthur O'Dwyer wrote:
On Monday, October 31, 2016 at 11:01:38 PM UTC-7, ant...@perezexcelsior.com wrote:
Currently, __func__ is part of the c++ standard, however __PRETTY_FUNCTION__ (part of GCC and Clang) provides significantly more information about a function.

FWIW, my attitude toward __PRETTY_FUNCTION__ is the same as my attitude toward "#pragma once" (in the recent thread on that subject).  I love it and evangelize its usage; but since it already exists and works great (for me and everyone I know), what's the benefit of standardizing it?  Just to antagonize the MSVC dev team? ;)  (MSVC supports something called _FUNCSIG but not __PRETTY_FUNCTION__. I'd love for them to get on that, but I don't think the ISO C++ committee is the right vector for MSVC feature requests.)

That's the whole point of standardizing anything: so that all implementations can agree on what a particular thing means and how it will behave. You're basically saying that if GCC and Clang both implement some feature, then who cares if it's part of the standard or not.

The C++ standard is not just for people using GCC or Clang.

Thiago Macieira

unread,
Nov 1, 2016, 9:19:07 PM11/1/16
to std-pr...@isocpp.org
Em terça-feira, 1 de novembro de 2016, às 18:02:04 PDT, Nicol Bolas escreveu:
> That's the whole point of standardizing *anything*: so that all
> implementations can agree on what a particular thing means and how it will
> behave. You're basically saying that if GCC and Clang both implement some
> feature, then who cares if it's part of the standard or not.
>
> The C++ standard is not just for people using GCC or Clang.

Except that we'd standardise that it is a string literal of unknown and
arbitrary contents. What's the point of standardising that?

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center

Nicol Bolas

unread,
Nov 1, 2016, 11:04:11 PM11/1/16
to ISO C++ Standard - Future Proposals


On Tuesday, November 1, 2016 at 9:19:07 PM UTC-4, Thiago Macieira wrote:
Em terça-feira, 1 de novembro de 2016, às 18:02:04 PDT, Nicol Bolas escreveu:
> That's the whole point of standardizing *anything*: so that all
> implementations can agree on what a particular thing means and how it will
> behave. You're basically saying that if GCC and Clang both implement some
> feature, then who cares if it's part of the standard or not.
>
> The C++ standard is not just for people using GCC or Clang.

Except that we'd standardise that it is a string literal of unknown and
arbitrary contents. What's the point of standardising that?

Well, I assumed that if it were going to be standardized, it would be standardized to have specific content. Yes, if it's just "it's a string of some kind which probably represents the function declaration," then standardizing it has no point.

If we can't give it a specific, well-understood format, then it'd be better if we all just waited for reflection so that we could build it ourselves.

Jim Porter

unread,
Nov 1, 2016, 11:33:58 PM11/1/16
to std-pr...@isocpp.org
On 11/1/2016 10:04 PM, Nicol Bolas wrote:
> Well, I assumed that if it were going to be standardized, it would be
> standardized to have /specific/ content. Yes, if it's just "it's a
> string of some kind which probably represents the function declaration,"
> then standardizing it has no point.

Even if you standardized the general format of how the content is laid
out, like how you show template arguments, that doesn't necessarily mean
every compiler will show the same thing. For instance, if you have a
function `std::string foo()`, __PRETTY_FUNCTION__ could be:

* std::string foo() -- clang
* std::basic_string<char> foo() -- gcc
* std::__cxx11::basic_string<char> foo() -- gcc with libstdc++'s C++11 ABI
* class std::basic_string<char,struct std::char_traits<char>,class
std::allocator<char> > __cdecl foo(void) -- msvc (via __FUNCSIG__)

All of these are valid, and I don't think there's a great way to say in
general which one is the *most* valid; if you say
`std::basic_string<char>` in your declaration, but `std::string` in your
definition, which do you prefer? (Arguably the latter.) While it's true
we could standardize this as well, I'm not sure if it's worth it when we
could focus on standardizing reflection.

- Jim

Viacheslav Usov

unread,
Nov 3, 2016, 6:42:09 AM11/3/16
to ISO C++ Standard - Future Proposals
On Tue, Nov 1, 2016 at 7:01 AM, <ant...@perezexcelsior.com> wrote:

> Currently, __func__ is part of the c++ standard, however __PRETTY_FUNCTION__ (part of GCC and Clang) provides significantly more information about a function. It's more useful for printing debugging information and error messages, and in addition it provides a method for getting the programmatic name of a type.

C++ has no way to refer to the current function. That is why we use __func__ and __PRETTY_FUNCTION__ to refer to some information on the current function. That may also be why we keep seeing proposals "let's standardise this way of getting stack traces".

I'd rather have the real problem fixed than more hacks standardised.

Cheers,
V.

sob...@gmail.com

unread,
Jun 30, 2018, 1:03:17 AM6/30/18
to ISO C++ Standard - Future Proposals, db0...@gmail.com
I would argue that the key feature of __PRETTY_FUNCTION__ is that for template functions, it contains the abstract signature followed by a list of parameter/argument pairs, while __FUNCSIG__ contains the signature with substitutions in-place. Pardon my vocabulary if that isn't quite clear - hopefully an example will go further.

#include <iostream>
#include <utility>
template<class S, template<class...> class TT, class T = TT<S,S>>
const char *pretty(T && t = {S(), S()})
{ return __PRETTY_FUNCTION__; }
//{ return __FUNCSIG__; }
int main() {
    std
::cout << pretty<float, std::pair>() << std::endl;
   
//   GCC: const char* pretty(T&&) [with S = float; TT = std::pair; T = std::pair<float, float>]
   
// Clang: const char *pretty(T &&) [S = float, TT = std::pair, T = std::__1::pair<float, float>]
   
//  MSVC: const char *__cdecl pretty<float,struct std::pair,struct std::pair<float,float>>(struct std::pair<float,float> &&)
}

I appreciate most of the arguments against standardization so far, but I still see a unique benefit to __PRETTY_FUNCTION__ in particular. The fact that it maps template arguments to template parameter names makes it much more valuable to anyone neck-deep in template metaprogramming. My example is simple and uses brief but unhelpful parameter names, so imagine a complex, heterogeneous parameter list, but with reasonably descriptive parameter names instead.

My argument for standardization would be that all the major compilers found the need to represent the current function one way or another, other than the nearly useless __func__; there's clearly enough demand for it, but without standardization, every use requires sniffing for each compiler and its extensions. (Every missed compiler, even those with a similar definition by another name, is either unable to compile at all, or gets a partial build if the default case shunts them around this section.) The standardization would not need to hammer out a specific format, as long as it specifies what information must be represented. __PRETTY_FUNCTION__ represents more information than the others, so ideally this information would be a part of the standard, but at least some representation of the signature seems reasonable, right?

I agree about reflection, but I think it's a separate concern, albeit tangentially related. We can have multiple concerns. If I'm mistaken, I'd happily take an equivalent definition via reflection if it were compiler-agnostic, but I assume this isn't what you intended, or this would just be a subset of what you'd like anyway.

Richard Hodges

unread,
Jun 30, 2018, 10:51:06 AM6/30/18
to std-pr...@isocpp.org
Wouldn't we prefer something like this?

namespace std
{
  struct current_funcition_details
  {
    constexpr string_view base_name() const;  // returns "foo"
    constexpr string_view full_name() const;  // returns e.g. "int bar::baz::foo(int, double) noexcept"
    size_t argument_count() const;
    array<type_info const&> argument_types() const; // could be something more constexpr-friendly to avoid instantiation of type_info
    // ... etc ...
  };

  constexpr auto current_function() -> current_function_details;
}


--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/c398c7ae-3490-457e-989c-9342bb9b580e%40isocpp.org.

Nicol Bolas

unread,
Jun 30, 2018, 10:56:08 AM6/30/18
to ISO C++ Standard - Future Proposals
On Saturday, June 30, 2018 at 10:51:06 AM UTC-4, Richard Hodges wrote:
Wouldn't we prefer something like this?

That's just reflection. Which we can all agree ought to be able to do what __PRETTY_FUNCTION__, only in a consistent way.

Richard Hodges

unread,
Jun 30, 2018, 2:06:25 PM6/30/18
to std-pr...@isocpp.org
> That's just reflection

Which just about the most requested feature and the most frustrating omission of the language.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.

Edward Catmur

unread,
Jun 30, 2018, 5:01:53 PM6/30/18
to ISO C++ Standard - Future Proposals
On Thursday, 3 November 2016 10:42:09 UTC, Viacheslav Usov wrote:
> On Tue, Nov 1, 2016 at 7:01 AM, <ant...@perezexcelsior.com> wrote:
>
>
> > Currently, __func__ is part of the c++ standard, however __PRETTY_FUNCTION__ (part of GCC and Clang) provides significantly more information about a function. It's more useful for printing debugging information and error messages, and in addition it provides a method for getting the programmatic name of a type.
>
>
> C++ has no way to refer to the current function. That is why we use __func__ and __PRETTY_FUNCTION__ to refer to some information on the current function. That may also be why we keep seeing proposals "let's standardise this way of getting stack traces".
>

Perhaps it's something of a hack, but it's trivial to declare and refer to a local class:

typeid(struct tag)

Demangling the name of that type, whether through reflection or through a stopgap solution, would I think be more generally useful than standardising a macro.

Andrew Tomazos

unread,
Jul 1, 2018, 8:27:41 PM7/1/18
to std-pr...@isocpp.org
On Sat, Jun 30, 2018 at 11:06 AM Richard Hodges <hodg...@gmail.com> wrote:
> That's just reflection

Which just about the most requested feature and the most frustrating omission of the language.

I believe a Reflection TS is in the works.

Reply all
Reply to author
Forward
0 new messages