Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++11 new function declaration syntax is not recognized correctly (Origin: bugzilla #730794) #5492

Open
doxygen opened this issue Jul 2, 2018 · 6 comments
Labels
needinfo reported bug is incomplete, please add additional info

Comments

@doxygen
Copy link
Owner

doxygen commented Jul 2, 2018

status NEEDINFO severity normal in component general for ---
Reported in version 1.8.7 on platform Other
Assigned to: Dimitri van Heesch

On 2014-05-27 07:52:16 +0000, heinzmann@schoeps.de wrote:

When using the new function declaration syntax introduced in C++11, the
return type is not recognized.

Example:

auto f(int a) -> char const * { return nullptr; }

The generated documentation shows 'auto' as the return type, instead of the
true return type 'char const *'.

On 2014-06-07 11:35:25 +0000, Dimitri van Heesch wrote:

I not sure what you mean or expect.

Doxygen shows the function prototype as you typed it including the '-> char
const *' part. Did you expect it to show

char const *f(int a)

instead?

On 2014-06-10 14:04:46 +0000, heinzmann@schoeps.de wrote:

Sorry for giving too misleading information. I should have tested more
cases.

When a function member in a class definition uses the old syntax, and the
member implementation later uses the new syntax, the member function summary
correctly shows the complete function signature using the old style. The
detailed member function documentation however shows the auto in front, but
not the arrow and the return type at the back. When both use the new syntax,
the detailed member function documentation is correct.

It would be either correct to use the old notation as in the class
definition, or the new one from the member implementation, but as it stands
it seems to get confused.

Maybe the parser doesn't recognize that the two are actually equivalent?

A more complete example that should trigger the fault would be:

struct X {
    int f(int a);
};

auto X::f(int a) -> int {
    return a;
}

The case raises an interesting general question:

Since there are now two equivalent syntaxes for the same function
definition, doxygen needs to decide somehow which one to use for the
documentation. There is no reason why one could not have multiple prototypes
using both syntaxes for the same function. Which one would doxygen choose?
Would it even be desirable to select one syntax globally, through
configuration settings in the Doxyfile, and doxygen would use that
regardless of which style was actually encountered in the code?
@doxygen doxygen added the needinfo reported bug is incomplete, please add additional info label Jul 19, 2018
@eyalroz
Copy link

eyalroz commented Jun 8, 2020

Note this was "reported" on StackOverflow in in 2013 already:

Doxygen and C++11 trailing return type

Indeed, it's expected that the return type be presented on the left. At the very least - that should be a configurable option.

@albert-github
Copy link
Collaborator

An more extended example: example.tar.gz
(bad style to have different forms in one file, but here just for the purpose of showing the problems)

/// \file

struct X {
    int f(int a);
    auto f1(int a) -> int;
    auto f2(int a) -> int;
};

/// Missing in detailed the -> int
auto X::f(int a) -> int {
    return a;
}

/// all OK
auto X::f1(int a) -> int {
    return a;
}

/// In the detailed type int and also -> int
int X::f2(int a) {
    return a;
}

@albert-github
Copy link
Collaborator

Difficult problem (especially the corner cases, some new ones with global variables and / or explicit detailed test as well: example1.tar.gz).

It looks like to have to do with the handling of the function type and the trailing return type and the way the later is stored (in a complete string, including trailing return type, and in separated parts for the arguments and the trailing return type).
It is likely that the handling through the functions:

  • setDefinition
  • argumentList
  • argumentList().setTrailingReturnType
  • declArgumentList().setTrailingReturnType
  • setArgsString

is not 100% consistent)

(I've been searching for the inconsistency but was not able to locate it :-( )

@jakefhyde
Copy link

jakefhyde commented May 27, 2021

Any update on this? I'm using the doxygen/sphinx/breathe/exhale pipeline, and as of 1.9.1 this issue is still around. Here is a minimum reproducible example:

#include <QObject>

namespace v0
{
inline namespace detail
{

template <typename ...Args>
auto connect(Args&&... args) -> decltype(QObject::connect(args...))
{}

} // namespace detail
} // namespace v0

And here is the generated doxygen output:

<templateparamlist>
  <param>
     <type>typename ...</type>
     <declname>Args</declname>
     <defname>Args</defname>
   </param>
 </templateparamlist>
 <type>auto</type>
 <definition>auto v0::detail::connect</definition>
 <argsstring>(Args &amp;&amp;... args) -&gt; decltype(QObject::connect(args...))</argsstring>
 <name>connect</name>
 <param>
   <type>Args &amp;&amp;...</type>
   <declname>args</declname>
 </param>
 <briefdescription>
 </briefdescription>
 <detaileddescription>

This works however:

#include <QObject>

namespace v0
{
inline namespace detail
{

template <typename ...Args>
decltype(QObject::connect(std::declval<Args>()...)) connect2(Args&&... args) 
{}

} // namespace detail
} // namespace v0

And here is the generated doxygen:

<templateparamlist>
  <param>
    <type>typename ...</type>
    <declname>Args</declname>
    <defname>Args</defname>
  </param>
</templateparamlist>
<type>decltype(QObject::connect(std::declval&lt; Args &gt;()...))</type>
<definition>decltype(QObject::connect(std::declval&lt;Args&gt;()...)) v0::detail::connect2</definition>
<argsstring>(Args &amp;&amp;... args)</argsstring>
<name>connect2</name>
<param>
  <type>Args &amp;&amp;...</type>
  <declname>args</declname>
</param>
<briefdescription>
</briefdescription>
<detaileddescription>

When using raw doxygen this isn't too obtrusive, but breathe's doxygenfunction requires a matching definition and argsstring so currently my only option is to do something like sed -i 's/-&gt.*<\/argsstring>/<\/argsstring>/'. For what it's worth I am also using the latest releases of breathe, sphinx, and exhale.

@vec-tk
Copy link

vec-tk commented Jul 26, 2022

Above:

Reported in version 1.8.7 on platform Other
From mosra/m.css#94 (comment):
I have just checked against Doxygen 1.9.3, and this issue is still present there.

Is this still an issue with doxygen 1.8.13 and the current 1.9.4 version?

@OleksandrKvl
Copy link

Hi, I don't know the internals of Doxygen but I think that in general case it's not possible to correctly deduce final return type as it might depend on the arguments. I think there should be an option to:

  • show only the placeholder, e.g. auto, as a return type and not the trailing return type clause
  • show trailing return type clause as a return type
  • show both (current behavior)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needinfo reported bug is incomplete, please add additional info
Projects
None yet
Development

No branches or pull requests

6 participants