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

[class] Returns for constructors and destructors should not have operands #3647

Closed
wants to merge 1 commit into from

Conversation

sdkrystian
Copy link
Contributor

[class.ctor] p6 says:

A return statement in the body of a constructor shall not specify a return value.

This makes it seem like one could have an operand of type void (since void has an empty set of values), but that is not permitted. Changing this to say that no operand is allowed is much clearer.

Additionally, there doesn't seem to be congruent wording for destructors regarding this.

@CaseyCarter
Copy link
Contributor

[stmt.return]/2 may cover this, in which case this text in [class.ctor]/6 is normative duplication.

@sdkrystian
Copy link
Contributor Author

Constructor/destructors aren't specified to have a return type, so I'd say such wording is very helpful, if not needed.

@CaseyCarter
Copy link
Contributor

Constructor/destructors aren't specified to have a return type, so I'd say such wording is very helpful, if not needed.

Sorry; what I'm trying to say (in a horribly roundabout way) is that [stmt.return] normatively allows only "A return statement with no operand" in a constructor or destructor, so the wording you're changing in [class.ctor] and the wording you're adding to [class.dtor] should both be notes.

@sdkrystian
Copy link
Contributor Author

return statement with no operand shall be used only in a function whose return type is cv void, a constructor, or a destructor.

To me this states the contexts that a return statement with no operand can appear in, rather than saying that a constructor/destructor can only have a return statement with no operand.

@CaseyCarter
Copy link
Contributor

CaseyCarter commented Jan 23, 2020

return statement with no operand shall be used only in a function whose return type is cv void, a constructor, or a destructor.

To me this states the contexts that a return statement with no operand can appear in, rather than saying that a constructor/destructor can only have a return statement with no operand.

Yes, and the following sentences specify that a return statement with an operand can appear only in a "function whose return type [has some property]". Since constructors and destructors formally are not functions - they are "introduced by a declaration whose declarator is a function-declarator" which is close but not quite the same thing - the net effect is to allow only return statements without operands in constructors and destructors. I will absolutely grant that "constructors and destructors are not functions" is extremely obscure and that [stmt.return]/2 could maybe use some clarification, but I believe the intent of the spec is that [stmt.return]/2 be authoritative for the fact in question rather than [class.ctor] or [class.dtor].

EDIT: (And now that I'm in core wording over my head, I'll shut up and let a core expert chime in.)

@sdkrystian
Copy link
Contributor Author

I find that reasoning for a constructor not being a function a bit weak, especially since we need them to be functions so they follow the normal overload resolution rules and other semantics for functions (passing arguments, etc). While it's not formally stated, it should be, as constructors are defined as a more restrictive subset of function as opposed to an entirely seperate entity.

@jensmaurer
Copy link
Member

I disagree with @CaseyCarter that constructors and destructors are not functions; they certainly are (some of them are "special member functions", for instance).

I think the operative statement in [stmt.return] p2 is "A return statement with any other operand shall be used only in a function whose return type is not cv void...."

The grammar in [class.ctor] p1 and [class.dtor] p1, together with [dcl.fct], makes it pretty clear that constructors and destructors do not have a return type, so you can't use "return operand" in these functions.

I'd suggest to turn the normative statement in [class.ctor] p6 into a note, add a note to [class.dtor] p5, split the last two sentences of [stmt.return] p2 into a separate paragraph, and add a note to that new paragraph highlighting that constructors and destructors do not have a return type, and thus any return statement appearing in their function bodies cannot have an operand.

@sdkrystian
Copy link
Contributor Author

In my option, we if we take that route, it should be specified that constructors and destructors have no return type explicitly with normative wording, since they are functions.

@CaseyCarter
Copy link
Contributor

I disagree with @CaseyCarter that constructors and destructors are not functions; they certainly are (some of them are "special member functions", for instance).

Everything is clearer in the day: [dcl.fct] specifies function types (and rules out constructors and destructors) whereas [dcl.fct.def] specifies function definitions (and admits constructors and destructors). "constructors and destructors are not functions" is incorrect nonsense, whereas "not all functions have a function type" is correct nonsense ;). Sorry for the noise, and thanks for the correction.

@sdkrystian
Copy link
Contributor Author

I think that a good course of action would be to add the following wording to [class.ctor] and [class.dtor]:

The type of the constructor is "noexcept(opt) function of parameter-type-list", where noexcept is present only if the exception specification is non-throwing.
The type of the prospective destructor is "noexcept(opt) function of parameter-type-list", where noexcept is present only if the exception specification is non-throwing.

And add notes after these sentences to further clarify that they have no return type, if the absence of "return T" was not clear enough. This clarifies the type of the constructor and destructor and reinforces that they are function (even @CaseyCarter was confused on that front!). @jensmaurer's changes to [stmt.return] would also be desirable, along with the removal of [class.ctor] p6.

@zygoloid zygoloid added the decision-required A decision of the editorial group (or the Project Editor) is required. label Mar 4, 2020
@jensmaurer
Copy link
Member

jensmaurer commented Dec 4, 2020

Editorial meeting: stmt.return p2: change "whose return type" to "that has a return type" to more clearly hint that "no return type" is an option. Also apply Jens' suggestions for class.ctor p6 etc. Forward the part about the function type [dcl.meaning] of constructors and destructors to CWG.

@jensmaurer jensmaurer removed the decision-required A decision of the editorial group (or the Project Editor) is required. label Dec 4, 2020
@jensmaurer
Copy link
Member

jensmaurer commented Jul 5, 2021

Superseded by #4737

@jensmaurer jensmaurer closed this Jul 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants