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...
Have you any thoughts about #1, #2, #3?
--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.
Cheerily," -- Richard Harter