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

Feature request: doc for unnamed parameters #6926

Open
marcalff opened this issue Apr 13, 2019 · 19 comments
Open

Feature request: doc for unnamed parameters #6926

marcalff opened this issue Apr 13, 2019 · 19 comments
Labels
C/C++ enhancement a request to enhance doxygen, not a bug

Comments

@marcalff
Copy link

marcalff commented Apr 13, 2019

Some times in C/C++, function parameters that are not used are not named, to avoid compiler warnings. This happens typically when a prototype can not change, for binary compatibility reasons.

To document this function:

void move(double x, double y, double /* unused z */, double /* unused t */);

or with even less comments:

void move(double x, double y, double, double);

the suggestion is to support:

@param x (doc for x)
@param y (doc for y)
@param 3 This is for z, for future use. We only support 2D in this version, 3D is for the next release.
@param 4 This is for t, but we got overly optimistic with the design. Don't count on time travel to be supported any time soon.

Numbers refer to parameters by ordinal position.

Very low priority, just documenting the idea.

@albert-github albert-github added C/C++ enhancement a request to enhance doxygen, not a bug labels Apr 13, 2019
@albert-github
Copy link
Collaborator

@ThomasFeher
Copy link

Just found this issue because I searched for a way to document an unnamed parameter. My use case is "tag dispatching", where one or several parameters are used just to increase the number of overloaded functions without using the value of these "tag parameters".

@eyalroz
Copy link

eyalroz commented Jul 3, 2020

So, I asked the StackOverflow question, and just noticed this bug. I'm still hoping this feature could be implemented... +1.

@albert-github
Copy link
Collaborator

The current syntax for the \param command is:

\param'['dir']' { parameter description }

and the <parameter-name> has to match, which is obviously not the case when in the implementation this [parameter is not specified and it is present for compatibility reasons or not needed in the, overloaded, function.

I've had some thoughts about the possibilities:

  1. \param'['dir']' <number> { parameter description }
    e.g. \param 1 This is for z, for future use.
    I don't think that this possibility is not a good choice as it is not really distinct from other parameters.
  2. \param'['dir']' <special-parameter-name> { parameter description }
    e.g. \param #1 This is for z, for future use.
    or \param @1 This is for z, for future use.
    I don't think that this possibility is not a good choice as it is not really distinct from other parameters and more importantly for some languages the sued special-parameter-name might be a valid name so here we couldn't distinguish between a 'real' parameter from a 'dummy' parameter.
  3. \param['{'option'}']'['dir']' <number> { parameter description }
    for the option I'm thinking about 'unnamed' or 'noname' in this way it is made clear that we have to do with an unnamed parameter in the definition. We need a sequence number (of the i-th unnamed parameter) here to determine the place of the parameter in the list.
    So something like:
    /// @param x (doc for x)
    /// @param y (doc for y)
    /// @param{unnamed} 1 This is for z, for future use. We only support 2D in this version, 3D is for the next release.
    /// @param{unnamed} 2 This is for t, but we got overly optimistic with the design. Don't count on time travel to be supported any time soon.
    void move(double x, double y, double, double);
    
    Discussion points here are certainly:
    • name of the option
    • the used number (sequence number of the i-th unnamed parameter or sequence number (of the i-th parameter)
    • warnings

My preference is certainly the third possibility.
@doxygen what is your opinion?

@doxygen
Copy link
Owner

doxygen commented Jul 4, 2020

Given that \param requires a parameter name as argument and a real parameter name cannot be a number, I don't see a real problem with option 1. It is basically the same as option 3 without the explicit {unnamed}, which feels a bit verbose/redundant, even though the intention is more clearly expressed of course.

I would say the number should be the i-th parameter (starting with 1), not just the i-th unnamed parameter.
I can imagine some people may prefer to document all parameters using numbers (as it is shorter to write than the full parameter name).

Checks that can be done:

  • For the "have all parameters been documented" check, the numbers need to be taken into account as well.
  • If the number is larger than the number of parameters it is a mistake and needs to produce a warning.
  • If a parameter is documented by name and also by number it is probably a mistake (parameter added without updating the numbers) and needs to give a warning.

@eyalroz
Copy link

eyalroz commented Jul 4, 2020

I agree with @doxygen that an option-1-like approach is sound.

For languages like C and C++, I also like the suggestion for the number to refer to the overall parameter index. But what about languages which have both named and extra positional parameters? ... if, in that case, the numbers refer only to positional parameters, then I support that as well.

@albert-github
Copy link
Collaborator

@eyalroz Can you give an example of "languages which have both named and extra positional parameters"?

@eyalroz
Copy link

eyalroz commented Jul 4, 2020

@albert-github : I'm not sure, but perhaps Python?

@albert-github
Copy link
Collaborator

I can see in python something like positional arguments see:

So I think we are talking here about parameters and I have not yet found something like "positional parameters".

@albert-github
Copy link
Collaborator

A point not taken into account yet is how to show the "unnamed" parameter in the output.
At the moment we would have in the field for the name the specified number, would this be sufficient or should this be made more explicit? How?

Regarding the check:

For the "have all parameters been documented" check, the numbers need to be taken into account as well.

this would give, possibly, extra warnings, at the moment "unnamed" parameters are silently ignored or is the intention that when one numbered parameter is documented all numbered parameters should be documented?

@albert-github
Copy link
Collaborator

albert-github commented Jul 6, 2020

There is a nice corner case where doxygen has some problems:

/// \file

/// just a typedef
typedef int X;

///   @param x (doc for x)
void type0(const int x,const X);                                                                                                    
///   @param x (doc for x)
void type1(const int x,const int);

which results in:

bb.h:7: warning: The following parameter of type0(int x, const X) is not documented:
  parameter 'X'

as far as I know the "type0" and "type1" are identical, though I don't think this is is a problem for this issue but should be solved separately but it will lead in this case when documenting the functions as:

///   @param x (doc for x)
///   @param 2 the unused parameter

to some warnings as doxygen sees in the parameter list an X as argument and in the documentation a 2 at that place.

Do we seen any solutions for this problem?

@eyalroz
Copy link

eyalroz commented Jul 6, 2020

@albert-github : So, the behavior you describe seems to be a bug. If it's resolved, I don't see why you identify a problem.

As for the question of "what if a parameter name is specified, but the doxygen comments documents by parameter index?" - My answer would be that the documentation will not mention the parameter name again, e.g. something like

void type1(const int x,const int);

Blah blah brief field.

Parameters:
* x  - doc for x
* const int - doc for the unnamed parameter

@albert-github
Copy link
Collaborator

albert-github commented Jul 6, 2020

@eyalroz this is, also in my opinion, a bug, but I don't see an easy solution for it so I mentioned it here as a potential problem.
I created an issue for it: #7894.

Regarding the * const int - doc for the unnamed parameter what happens when there would be something like:

void type2(const int x,const int, const int);

Maybe we need something like

name description
x doc for x
parameter 2:
const int
doc for the unnamed parameter
parameter 3:
const int
doc for the unnamed parameter

@eyalroz
Copy link

eyalroz commented Jul 6, 2020

Oh, you mean saying "parameter N:" instead of just "const int:" - fine by me. I don't mind. Plus, remember - if the initial implementation is not aesthetic enough / annoying to users, it can always be tweaked later. No need to "bikeshed" this too much.

@dfrib
Copy link

dfrib commented Oct 1, 2021

No need to "bikeshed" this too much.

An attempt at resuscitating this issue. Imo any of the last proposals above sounds great.

@eric-hughes-tiledb
Copy link

resuscitating this issue

Reiterating this sentiment, with detail. I found this issue after writing a pair of constructors of the following form. The effect is to enable exactly one of the constructors; which one ultimately depends on external parameters. I'm not using C++20, where I simply would have written requires. Instead I needed some SFINAE finesse:

template<class X = void, enable_if_t<a_predicate<X>::value,int> = 0 > a_class(...)
template<class X = void, enable_if_t<!a_predicate<X>::value,int> = 0 > a_class(...)

The constructors are to be called without explicit template arguments. The second argument is only present allow a substitution to succeed or fail. Neither argument is used in the code, yet if the second argument is named it generates a warning, and our CI fails on warnings. Thus documenting this requires specifying an unnamed argument.

explicit {unnamed}, which feels a bit verbose/redundant, even though the intention is more clearly expressed of course

It's only slightly verbose, but not redundant. Expressing intent clearly is worth paying the price of a few characters. From the C++ Core Guidelines: P.1: Express ideas directly in code. If {unnamed} is too long, then perhaps use {parameter_name} and allow the name to be zero length.

@krzikalla
Copy link

I had the same problem. In my case a parameter is unused (non-pure virtual function in the base class), but needs to be documented.
How about introducing paramters names, which are only visible to doxygen?

void move(double x, double y, double /** @paramname z */, double /** @paramname time */);

The rest is straightforward. This has the additional advantage, that the doc then contains descriptive parameter names instead of pure numbers.

@jwakely
Copy link
Contributor

jwakely commented Nov 28, 2022

That seems visually noisy, and pretty ugly IMHO.

Standardese just supports @param 1 to refer to params by position, which seems ideal. This is completely unambiguous, because 1 is not a valid identifier, so cannot be a real param name.

@jwakely
Copy link
Contributor

jwakely commented Nov 28, 2022

Standardese also supports an @exclude command which can be used to exclude individual parameters (or entire functions, classes etc) from the generated docs. That is a much better solution for a tparam that is only used for SFINAE constraints, as in @eric-hughes-tiledb's comment above. Instead of having to give a dummy name to the param and document it as "ignore this", or having doxygen complain that it's not documented, just mark it as "exclude from API docs".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C/C++ enhancement a request to enhance doxygen, not a bug
Projects
None yet
Development

No branches or pull requests

9 participants