void func(); struct A { A() { return func(); } };
Why should it be allowed? Is this for some code generation solution or some such?
While I won't make a fuss about macros, the question that pops to mind is whether the implementation of the macro is the most appropriate and whether it would not be feasible to rewrite it, say to:
#define RETURN do { func(); return; } while (false)
That would not require a change in the standard. Of course I imagine that the original macro is more complicated and it might not be as simple as the code above... but I have the feeling something like that should be feasible.
David
What you are asking for is an exception to the rule.
But in the case that you are proposing, the type of 'f' does not matter at all, you are not allowed to return a value from a constructor, so no matter how generic the code 'return f(std::forward(args)...);' is ill-formed. What you are asking for is an exception to the rule.
Stated in a different way, for regular functions, enabling 'X g() { return f(); }' creates uniformity. No matter what 'X' is (including void) the syntax is uniform, you don't need to special case. Allowing 'T::T() { return f(); }' breaks uniformity by creating a special case in which a return statement inside a constructor can take an argument, but only if 'f' has a void return type.
My personal opinion is that the less special cases and exceptions the simpler the language. And in this case I don't see a strong enough motivating example for an exception.
Am Mittwoch, 26. Juni 2013 15:57:09 UTC+2 schrieb David Rodríguez Ibeas:I can see your point.What you are asking for is an exception to the rule.
I am surprised on the comments that the exception here are constructors not returning anything vs. functions being able to return.
Constructors are special beasts, there are many rules that are different in constructors and the rest of the code,
Focusing on the possibility of returning a value, when declaring the constructor the syntax does not allow to declare a return type which is consistent with the definition not being able to return one, when the constructor is executed there is no possible way of retrieve a value.
While in the lowest possible level the constructor will be transformed by the compiler into a function, at the C++ level constructors and destructors are very different from functions at many different levels. At this point constructors are a subcategory of functions with a consistent set of rules,
and the suggestion is adding one more corner case. Where we currently say "constructors cannot return a value" the proposal is to add a tail "... except when the value is void".
We are creating an exception within the rules for constructors.
On 26 June 2013 10:08, David Rodríguez Ibeas <dib...@ieee.org> wrote:
I am surprised on the comments that the exception here are constructors not returning anything vs. functions being able to return.
void functions don't return anything either. Other than (what is probably) a historical accident, why should the rules for the bodies of those functions be any different? This is just one more inconsistency that makes the language a little more difficult to learn and use.
Constructors are special beasts, there are many rules that are different in constructors and the rest of the code,
And it would be more uniform if we could minimize those differences. This proposal helps that.
Focusing on the possibility of returning a value, when declaring the constructor the syntax does not allow to declare a return type which is consistent with the definition not being able to return one, when the constructor is executed there is no possible way of retrieve a value.
I don't see how that is any different than a void function.
While in the lowest possible level the constructor will be transformed by the compiler into a function, at the C++ level constructors and destructors are very different from functions at many different levels. At this point constructors are a subcategory of functions with a consistent set of rules,
Consistent with respect to what?
and the suggestion is adding one more corner case. Where we currently say "constructors cannot return a value" the proposal is to add a tail "... except when the value is void".
Why should the rules be different than with void functions, other than "we can"?
We are creating an exception within the rules for constructors.
I just don't understand this. If we change the rules for constructors, it won't be an exception within the rules of constructors, pretty much by definition.
This way it'll be one less exception within the rules for bodies of functions, whether they be constructors or not.
Am 26.06.2013 19:02 schrieb "David Rodríguez Ibeas" <dib...@ieee.org>:
>
> I guess I did not get my point through...
>
>
> On Wed, Jun 26, 2013 at 11:24 AM, Nevin Liber <ne...@eviloverlord.com> wrote:
>>
>> On 26 June 2013 10:08, David Rodríguez Ibeas <dib...@ieee.org> wrote:
>>>
>>> I am surprised on the comments that the exception here are constructors not returning anything vs. functions being able to return.
>>
>>
>> void functions don't return anything either. Other than (what is probably) a historical accident, why should the rules for the bodies of those functions be any different? This is just one more inconsistency that makes the language a little more difficult to learn and use.
>>
>>>
>>> Constructors are special beasts, there are many rules that are different in constructors and the rest of the code,
>>
>>
>> And it would be more uniform if we could minimize those differences. This proposal helps that.
>
>
> Does it? If you consider a constructor equivalent to a void function then this should be allowed:
>
> struct U {};
> struct T { T(); };
> T::T() { return U(); }
>
This incorrect. The expression "U ()" is not only a call to Us constructor, but does considerably more. It just contains an implicit call to the constructor as an subexpression. The type of "U ()" is U.
Supporting this would actually erase a hole in the type system. Currently a statement like "a function has a return type" is incorrect because the function type of a constructor is not defined.
> Since that is allowed in the case of void functions in the case of functions:
>
> void f();
> void g() { return f(); }
>
This comparison is therefor unsound.
> Although the semantics are completely different, and they are different because constructors are not functions and you cannot call a constructor,
Incorrect. They are functions. You just cannot call them directly. Directly refering to the constructor of U is done by U::U (which is allowed in declarative contexts such as friend declarations), not by a cast notation.
>
> My point is that constructors are not regular functions, so differences between constructors and regular functions are expected.
>
Conversion functions are special aswell, still you can say
operator void () {
return void ("folks");
}
> The rationale (if I understood it correctly) of allowing returning 'nothing' (i.e. returning void) was to support generic programming as in the example I provided before. That rationale does not apply here. If I am mistaken and there is a different rationale for 6.6.3/3 then disregard all this rant :)
>
In this thread it was shown that the rationale applies here aswell.
This incorrect. The expression "U ()" is not only a call to Us constructor, but does considerably more. It just contains an implicit call to the constructor as an subexpression. The type of "U ()" is U.
Supporting this would actually erase a hole in the type system. Currently a statement like "a function has a return type" is incorrect because the function type of a constructor is not defined.
Incorrect. They are functions. You just cannot call them directly. Directly refering to the constructor of U is done by U::U (which is allowed in declarative contexts such as friend declarations), not by a cast notation.
the example I provided before. That rationale does not apply here. If I am mistaken and there is a different rationale for 6.6.3/3 then disregard all this rant :)
In this thread it was shown that the rationale applies here aswell.