Shao Miller <> writes:
> On 1/22/2013 23:28, Ben Bacarisse wrote:
>> Shao Miller <> writes:
>>
>>> On 1/22/2013 17:37, Ben Bacarisse wrote:
>>>> Shao Miller <> writes:
>>>>
>>>>> On 1/22/2013 16:02, Ben Bacarisse wrote:
>>>>>> Ike Naar <> writes:
>>>>>>
>>>>>>> On 2013-01-22, Noob <root@127.0.0.1> wrote:
>>>>
>>>> <snipping has lost the fact that struct toto has const qualified members>
>>>>
>>>>>>> And how about returning by value?
>>>>>>>
>>>>>>> struct toto foo(int i, float f, void *p)
>>>>>>> {
>>>>>>> struct toto res = {i, f, p};
>>>>>>> return res;
>>>>>>> }
>>>>>>
>>>>>> This limits what you can do with it for the same reason. You can't
>>>>>> assign a strust toto because of its const members.
>>>>>
>>>>> Are you sure about that? 'res' undergoes lvalue conversion and no
>>>>> longer has qualified type.
>>>>
>>>> Am I sure about what? I think you know that you can't assign to a
>>>> struct toto object, so are you saying if I am sure that returning this
>>>> struct type limits what one can do with it?
>>>>
>>>> A pointer to allocated storage is more flexible (because you have
>>>> control over the lifetime) and the function as given is almost identical
>>>> to a simple expression: (struct toto){i, f, p}.
>>>>
>>>
>>> Sorry, Ben. I've approached this in my head in four ways:
>>>
>>> 1. (Non-preferred; must be wrong because of lvalue conversion)
>>>
>>> 'res', before lvalue conversion, has a compatible type with the return
>>> type of the function, so "the value is converted as if by assignment
>>> to an object having the return type of the function" does not apply,
>>> and "the value of" 'res' "is returned to the caller as the value of
>>> the function call expression"
>>>
>>> 2. (More preferred than #1)
>>>
>>> 'res' undergoes lvalue conversion and yields an unqualified type with
>>> the value. This type is incompatible with the return type of the
>>> function, so "the value is converted as if by assignment to an object
>>> having the return type of the function", but the footnote reminds us
>>> that "The return statement is not an assignment." So there might be
>>> one or more differences.
>>>
>>> Looking at 6.5.16p1, it cannot apply as it is, since "an object having
>>> the return type of the function" isn't the same as "a modifiable
>>> lvalue designating an object having the return type of the function."
>>> We need to twist it a bit. There's also no direct discussion of
>>> conversion for the RHS operand... That's "2 strikes". So what if we
>>> drop that bit and move on to 6.5.16.1?
>>>
>>> Alternatively to moving on, there's a constraint violation (as you've
>>> mentioned) based on "modifiable". But why pick "modifiable" and not
>>> "lvalue"? 
>>>
>>> Looking at 6.5.16.1p1, the return type of 'foo' and the unqualified
>>> type of rvalue from 'res' satisfy the second bullet. Then p2 does
>>> indeed refer back to 6.5.16p2, but only insofar as the type of the
>>> assignment-expression. The type of the assignment-expression so
>>> happens to be the unqualified type of 'struct toto', which is the same
>>> type as the rvalue from 'res', so there's actually no conversion for
>>> the rvalue from 'res'.
>>>
>>> 3. (Preferred)
>>>
>>> 6.7.3p4: "The properties associated with qualified types are
>>> meaningful only for expressions that are lvalues.132)" But "the value
>>> of the function call expression" is never an lvalue, so perhaps the
>>> return type of a function is never qualified.
>>>
>>> In that case, the lvalue conversion of 'res' yields an rvalue whose
>>> type is already compatible with the return type, so "the value is
>>> converted as if by assignment to an object having the return type of
>>> the function" does not apply, and "the value of" 'res' "is returned to
>>> the caller as the value of the function call expression".
>>>
>>> If #3 is true, the wording could be a bit clearer.
>>>
>>> 4. (D'oh!)
>>>
>>> Unfortunately, I don't think any of #1, #2, #3 is true, due to
>>> 6.7.3p9: "...If the specification of a function type includes any type
>>> qualifiers, the behavior is undefined.136)" (Since at least C90.) I
>>> think that means that 'foo' can't be declared that way.
>>
>> You wrote eight paragraphs of stuff that you don't think is true?
>>
>
> Well I was hopeful for #3, but seemed to recall having previously read
> some other bit of Standard text contradicting it. When I went
> looking, I came across 6.7.3p9 and it looked like it was the
> antagonist. Perhaps that wasn't it, after all.
>
>> How do you interpret 6.7.3 p9 so that the function above is undefined,
>> but const char *int_to_str(int) is not?
>>
>>> (This is Ike Naar's 'foo', obviously. Citations relative to N1570.)
>
> Well I was thinking along the lines of the qualification of the return
> type's type category, but maybe not...
I don't know what a type's type category is so I can't comment here.
> Have you any thoughts about #1, #2, #3?
The return type is the same as that of the function so no conversion
takes place. The value of res is the value returned. It does not seem
to be complicated to me.
--
Ben.