Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #30504 > unrolled thread

Initializing a malloc'ed struct whose fields are const with run-time values

Started byNoob <root@127.0.0.1>
First post2013-01-22 16:36 +0100
Last post2013-01-22 20:48 -0800
Articles 20 on this page of 64 — 13 participants

Back to article view | Back to comp.lang.c


Contents

  Initializing a malloc'ed struct whose fields are const with run-time values Noob <root@127.0.0.1> - 2013-01-22 16:36 +0100
    Re: Initializing a malloc'ed struct whose fields are const with run-time values Shao Miller <sha0.miller@gmail.com> - 2013-01-22 11:23 -0500
      Re: Initializing a malloc'ed struct whose fields are const with run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-22 21:26 +0000
        Re: Initializing a malloc'ed struct whose fields are const with run-time values James Kuyper <jameskuyper@verizon.net> - 2013-01-22 16:41 -0500
      Re: Initializing a malloc'ed struct whose fields are const with run-time values William Ahern <william@wilbur.25thandClement.com> - 2013-01-22 13:25 -0800
        Re: Initializing a malloc'ed struct whose fields are const with run-time values Shao Miller <sha0.miller@gmail.com> - 2013-01-22 23:17 -0500
      Re: Initializing a malloc'ed struct whose fields are const with run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-23 13:09 +0000
        Re: Initializing a malloc'ed struct whose fields are const with run-time values Noob <root@127.0.0.1> - 2013-01-23 14:16 +0100
          Re: Initializing a malloc'ed struct whose fields are const with run-time values "BartC" <bc@freeuk.com> - 2013-01-23 13:25 +0000
            Re: Initializing a malloc'ed struct whose fields are const with run-time values Noob <root@127.0.0.1> - 2013-01-23 15:21 +0100
              Re: Initializing a malloc'ed struct whose fields are const with run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-23 14:56 +0000
                Re: Initializing a malloc'ed struct whose fields are const with run-time values Noob <root@127.0.0.1> - 2013-01-23 16:40 +0100
                  Re: Initializing a malloc'ed struct whose fields are const with run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-23 18:26 +0000
                  Re: Initializing a malloc'ed struct whose fields are const with run-time values Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-23 20:39 -0800
              Re: Initializing a malloc'ed struct whose fields are const with run-time values Shao Miller <sha0.miller@gmail.com> - 2013-01-23 17:14 -0500
    Re: Initializing a malloc'ed struct whose fields are const with run-time values Ike Naar <ike@sverige.freeshell.org> - 2013-01-22 17:59 +0000
      Re: Initializing a malloc'ed struct whose fields are const with run-time values Shao Miller <sha0.miller@gmail.com> - 2013-01-22 14:09 -0500
        Re: Initializing a malloc'ed struct whose fields are const with run-time values Noob <root@localhost> - 2013-01-22 21:59 +0100
          Re: Initializing a malloc'ed struct whose fields are const with run-time values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-22 21:19 +0000
          Re: Initializing a malloc'ed struct whose fields are const with run-time values Shao Miller <sha0.miller@gmail.com> - 2013-01-22 23:47 -0500
        Re: Initializing a malloc'ed struct whose fields are const with run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-22 21:05 +0000
          Re: Initializing a malloc'ed struct whose fields are const with run-time values Shao Miller <sha0.miller@gmail.com> - 2013-01-22 16:15 -0500
      Re: Initializing a malloc'ed struct whose fields are const with   run-time values Ian Collins <ian-news@hotmail.com> - 2013-01-23 09:43 +1300
        Re: Initializing a malloc'ed struct whose fields are const with   run-time values William Ahern <william@wilbur.25thandClement.com> - 2013-01-22 13:19 -0800
          Re: Initializing a malloc'ed struct whose fields are const with   run-time values William Ahern <william@wilbur.25thandClement.com> - 2013-01-22 13:35 -0800
            Re: Initializing a malloc'ed struct whose fields are const with   run-time values Ian Collins <ian-news@hotmail.com> - 2013-01-23 10:45 +1300
              Re: Initializing a malloc'ed struct whose fields are const with   run-time values Shao Miller <sha0.miller@gmail.com> - 2013-01-22 17:07 -0500
              Re: Initializing a malloc'ed struct whose fields are const with  run-time values Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-22 21:29 -0800
                Re: Initializing a malloc'ed struct whose fields are const with  run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-23 13:54 +0000
                  Re: Initializing a malloc'ed struct whose fields are const with  run-time values Shao Miller <sha0.miller@gmail.com> - 2013-01-23 17:08 -0500
                    Re: Initializing a malloc'ed struct whose fields are const with    run-time values Ian Collins <ian-news@hotmail.com> - 2013-01-24 11:29 +1300
                      Re: Initializing a malloc'ed struct whose fields are const with    run-time values Shao Miller <sha0.miller@gmail.com> - 2013-01-23 18:26 -0500
                        Re: Initializing a malloc'ed struct whose fields are const with      run-time values Ian Collins <ian-news@hotmail.com> - 2013-01-24 14:03 +1300
                          Re: Initializing a malloc'ed struct whose fields are const with      run-time values Shao Miller <sha0.miller@gmail.com> - 2013-01-23 23:58 -0500
                      Re: Initializing a malloc'ed struct whose fields are const with  run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-23 23:36 +0000
                        Re: Initializing a malloc'ed struct whose fields are const with  run-time values Ian Collins <ian-news@hotmail.com> - 2013-01-24 13:55 +1300
                          Re: Initializing a malloc'ed struct whose fields are const with  run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-24 02:44 +0000
                  Re: Initializing a malloc'ed struct whose fields are const with  run-time values Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-23 21:39 -0800
                    Re: Initializing a malloc'ed struct whose fields are const with  run-time values Shao Miller <sha0.miller@gmail.com> - 2013-01-24 00:54 -0500
                    Re: Initializing a malloc'ed struct whose fields are const with  run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-24 17:56 +0000
                      Re: Initializing a malloc'ed struct whose fields are const with  run-time values Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-24 13:58 -0800
          Re: Initializing a malloc'ed struct whose fields are const with   run-time values James Kuyper <jameskuyper@verizon.net> - 2013-01-22 16:37 -0500
            Re: Initializing a malloc'ed struct whose fields are const with  run-time values Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-22 21:22 -0800
        Re: Initializing a malloc'ed struct whose fields are const with  run-time values Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-22 21:06 -0800
          Re: Initializing a malloc'ed struct whose fields are const with  run-time values Ian Collins <ian-news@hotmail.com> - 2013-01-23 19:55 +1300
            Re: Initializing a malloc'ed struct whose fields are const with  run-time values Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-23 00:48 -0800
              Re: Initializing a malloc'ed struct whose fields are const with  run-time values Ian Collins <ian-news@hotmail.com> - 2013-01-23 23:06 +1300
      Re: Initializing a malloc'ed struct whose fields are const with run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-22 21:02 +0000
        Re: Initializing a malloc'ed struct whose fields are const with run-time values Shao Miller <sha0.miller@gmail.com> - 2013-01-22 16:12 -0500
          Re: Initializing a malloc'ed struct whose fields are const with run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-22 22:37 +0000
            Re: Initializing a malloc'ed struct whose fields are const with run-time values Shao Miller <sha0.miller@gmail.com> - 2013-01-22 22:29 -0500
              Re: Initializing a malloc'ed struct whose fields are const with run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-23 04:28 +0000
                Re: Initializing a malloc'ed struct whose fields are const with run-time values Shao Miller <sha0.miller@gmail.com> - 2013-01-23 00:07 -0500
                  Re: Initializing a malloc'ed struct whose fields are const with run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-23 14:04 +0000
      Re: Initializing a malloc'ed struct whose fields are const with run-time values Noob <root@localhost> - 2013-01-22 22:10 +0100
    Re: Initializing a malloc'ed struct whose fields are const with run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-22 21:13 +0000
      Re: Initializing a malloc'ed struct whose fields are const with run-time values Shao Miller <sha0.miller@gmail.com> - 2013-01-22 16:25 -0500
        Re: Initializing a malloc'ed struct whose fields are const with run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-22 22:21 +0000
      Re: Initializing a malloc'ed struct whose fields are const with run-time values William Ahern <william@wilbur.25thandClement.com> - 2013-01-22 13:32 -0800
        Re: Initializing a malloc'ed struct whose fields are const with run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-23 03:50 +0000
      Re: Initializing a malloc'ed struct whose fields are const with run-time values Nick Bowler <nbowler@draconx.ca> - 2013-01-22 21:43 +0000
        Re: Initializing a malloc'ed struct whose fields are const with run-time values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2013-01-23 03:45 +0000
          Re: Initializing a malloc'ed struct whose fields are const with run-time values Keith Thompson <kst-u@mib.org> - 2013-01-24 08:23 -0800
    Re: Initializing a malloc'ed struct whose fields are const with run-time values Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-22 20:48 -0800

Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →


#30524

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2013-01-22 21:05 +0000
Message-ID<0.fa15a69006d5f876011f.20130122210519GMT.87k3r53p4g.fsf@bsb.me.uk>
In reply to#30514
Shao Miller <sha0.miller@gmail.com> writes:

> On 1/22/2013 12:59, Ike Naar wrote:
>> On 2013-01-22, Noob <root@127.0.0.1> wrote:
>>> #include <stdlib.h>
>>> #include <string.h>
>>> struct toto *foo(int i, float f, void *p)
>>> {
>>>    struct toto s = { i, f, p };
>>>    struct toto *res = malloc(sizeof *res);
>>>    if (res != NULL) memcpy(res, &s, sizeof s);
>>
>> Why memcpy instead of an assignment?
>>      if (res != NULL) *res = s;
>>
>
> Because they amount to the same thing, behind the scenes, on a few
> implementations? ;)

But in front of the scenes, they are very different!  The assignment is
a constraint violation.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#30529

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-22 16:15 -0500
Message-ID<kdmvgr$jbm$1@dont-email.me>
In reply to#30524
On 1/22/2013 16:05, Ben Bacarisse wrote:
> Shao Miller <sha0.miller@gmail.com> writes:
>
>> On 1/22/2013 12:59, Ike Naar wrote:
>>> On 2013-01-22, Noob <root@127.0.0.1> wrote:
>>>> #include <stdlib.h>
>>>> #include <string.h>
>>>> struct toto *foo(int i, float f, void *p)
>>>> {
>>>>     struct toto s = { i, f, p };
>>>>     struct toto *res = malloc(sizeof *res);
>>>>     if (res != NULL) memcpy(res, &s, sizeof s);
>>>
>>> Why memcpy instead of an assignment?
>>>       if (res != NULL) *res = s;
>>>
>>
>> Because they amount to the same thing, behind the scenes, on a few
>> implementations? ;)
>
> But in front of the scenes, they are very different!  The assignment is
> a constraint violation.
>
> <snip>
>

Yes, that's quite true.  I was teasing about a bad reason for doing it, 
not pointing out a good reason for doing it. :)

-- 
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily,"  -- Richard Harter

[toc] | [prev] | [next] | [standalone]


#30520 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromIan Collins <ian-news@hotmail.com>
Date2013-01-23 09:43 +1300
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<am8bvaFbgsgU2@mid.individual.net>
In reply to#30511
Ike Naar wrote:
> On 2013-01-22, Noob <root@127.0.0.1> wrote:
>> #include <stdlib.h>
>> #include <string.h>
>> struct toto *foo(int i, float f, void *p)
>> {
>>    struct toto s = { i, f, p };
>>    struct toto *res = malloc(sizeof *res);
>>    if (res != NULL) memcpy(res, &s, sizeof s);
>
> Why memcpy instead of an assignment?
>      if (res != NULL) *res = s;
>
>>    return res;
>> }
>
> And how about returning by value?
>
>    struct toto foo(int i, float f, void *p)
>    {
>      struct toto res = {i, f, p};
>      return res;
>    }

Is that legal?  struct toto has const members, so can it be returned by 
value from a function?

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#30533 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromWilliam Ahern <william@wilbur.25thandClement.com>
Date2013-01-22 13:19 -0800
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<gcc3t9-6br.ln1@wilbur.25thandClement.com>
In reply to#30520
Ian Collins <ian-news@hotmail.com> wrote:
> Ike Naar wrote:
> > On 2013-01-22, Noob <root@127.0.0.1> wrote:
> >> #include <stdlib.h>
> >> #include <string.h>
> >> struct toto *foo(int i, float f, void *p)
> >> {
> >>    struct toto s = { i, f, p };
> >>    struct toto *res = malloc(sizeof *res);
> >>    if (res != NULL) memcpy(res, &s, sizeof s);
> >
> > Why memcpy instead of an assignment?
> >      if (res != NULL) *res = s;
> >
> >>    return res;
> >> }
> >
> > And how about returning by value?
> >
> >    struct toto foo(int i, float f, void *p)
> >    {
> >      struct toto res = {i, f, p};
> >      return res;
> >    }

> Is that legal?  struct toto has const members, so can it be returned by 
> value from a function?

What about foo().f? Does the simple return constitute modification of a
const-qualified lvalue?

I'm still not convinced that "modifying" a const-qualified member through
assignment of a non-const-qualified aggregate is undefined behaviour. But I
don't know enough about the rules of lvalues to prove it.

[toc] | [prev] | [next] | [standalone]


#30536 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromWilliam Ahern <william@wilbur.25thandClement.com>
Date2013-01-22 13:35 -0800
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<49d3t9-7rb.ln1@wilbur.25thandClement.com>
In reply to#30533
William Ahern <william@wilbur.25thandclement.com> wrote:
> Ian Collins <ian-news@hotmail.com> wrote:
> > Ike Naar wrote:
<snip>
> > > And how about returning by value?
> > >
> > >    struct toto foo(int i, float f, void *p)
> > >    {
> > >      struct toto res = {i, f, p};
> > >      return res;
> > >    }

> > Is that legal?  struct toto has const members, so can it be returned by 
> > value from a function?

> What about foo().f? Does the simple return constitute modification of a
> const-qualified lvalue?

> I'm still not convinced that "modifying" a const-qualified member through
> assignment of a non-const-qualified aggregate is undefined behaviour. But I
> don't know enough about the rules of lvalues to prove it.

Ok, now I am:

	C99 (N1256) 6.3.2.1

	A modifiable lvalue is an lvalue that does not have array type, does
	not have an incomplete type, does not have a const-qualified type,
	and if it is a structure or union, does not have any member
	(including, recursively, any member or element of all contained
	aggregates or unions) with a const-qualified type.

But foo().f should still be fine, I think.

[toc] | [prev] | [next] | [standalone]


#30540 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromIan Collins <ian-news@hotmail.com>
Date2013-01-23 10:45 +1300
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<am8fjtFbgsgU4@mid.individual.net>
In reply to#30536
William Ahern wrote:
> William Ahern <william@wilbur.25thandclement.com> wrote:
>> Ian Collins <ian-news@hotmail.com> wrote:
>>> Ike Naar wrote:
> <snip>
>>>> And how about returning by value?
>>>>
>>>>     struct toto foo(int i, float f, void *p)
>>>>     {
>>>>       struct toto res = {i, f, p};
>>>>       return res;
>>>>     }
>
>>> Is that legal?  struct toto has const members, so can it be returned by
>>> value from a function?
>
>> What about foo().f? Does the simple return constitute modification of a
>> const-qualified lvalue?
>
>> I'm still not convinced that "modifying" a const-qualified member through
>> assignment of a non-const-qualified aggregate is undefined behaviour. But I
>> don't know enough about the rules of lvalues to prove it.
>
> Ok, now I am:
>
> 	C99 (N1256) 6.3.2.1
>
> 	A modifiable lvalue is an lvalue that does not have array type, does
> 	not have an incomplete type, does not have a const-qualified type,
> 	and if it is a structure or union, does not have any member
> 	(including, recursively, any member or element of all contained
> 	aggregates or unions) with a const-qualified type.
>
> But foo().f should still be fine, I think.

So res above isn't a modifiable lvalue.

I just tried this code:

#include <stdio.h>

struct toto { const int i; const float f; const void *p; };

struct toto foo(int i, float f, void *p)
{
   return (struct toto){i, f, p};
}

int main(void)
{
   float f = foo( 1,2,NULL).f;
}

and gcc (-Wall -std=c99 -pedantic) compiles it, but Sun c99 (which tends 
to be both strict and conforming) rejects it with one error:

"x.c", line 7: left operand must be modifiable lvalue: op "="

where line 7 is the function return.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#30543 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-22 17:07 -0500
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<kdn2ji$878$1@dont-email.me>
In reply to#30540
On 1/22/2013 16:45, Ian Collins wrote:
> William Ahern wrote:
>> William Ahern <william@wilbur.25thandclement.com> wrote:
>>> Ian Collins <ian-news@hotmail.com> wrote:
>>>> Ike Naar wrote:
>> <snip>
>>>>> And how about returning by value?
>>>>>
>>>>>     struct toto foo(int i, float f, void *p)
>>>>>     {
>>>>>       struct toto res = {i, f, p};
>>>>>       return res;
>>>>>     }
>>
>>>> Is that legal?  struct toto has const members, so can it be returned by
>>>> value from a function?
>>
>>> What about foo().f? Does the simple return constitute modification of a
>>> const-qualified lvalue?
>>
>>> I'm still not convinced that "modifying" a const-qualified member
>>> through
>>> assignment of a non-const-qualified aggregate is undefined behaviour.
>>> But I
>>> don't know enough about the rules of lvalues to prove it.
>>
>> Ok, now I am:
>>
>>     C99 (N1256) 6.3.2.1
>>
>>     A modifiable lvalue is an lvalue that does not have array type, does
>>     not have an incomplete type, does not have a const-qualified type,
>>     and if it is a structure or union, does not have any member
>>     (including, recursively, any member or element of all contained
>>     aggregates or unions) with a const-qualified type.
>>
>> But foo().f should still be fine, I think.
>
> So res above isn't a modifiable lvalue.
>
> I just tried this code:
>
> #include <stdio.h>
>
> struct toto { const int i; const float f; const void *p; };
>
> struct toto foo(int i, float f, void *p)
> {
>    return (struct toto){i, f, p};
> }
>
> int main(void)
> {
>    float f = foo( 1,2,NULL).f;
> }
>
> and gcc (-Wall -std=c99 -pedantic) compiles it, but Sun c99 (which tends
> to be both strict and conforming) rejects it with one error:
>
> "x.c", line 7: left operand must be modifiable lvalue: op "="
>
> where line 7 is the function return.
>

That seems a bit odd.  'return' has little to do with an lvalue or object:

   "The properties associated with qualified types are meaningful only 
for expressions that are lvalues.132)"

So "as if by assignment" should be satisfied by:

   "the left operand has an atomic, qualified, or unqualified version of 
a structure or union type compatible with the type of the right;"

No?

-- 
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily,"  -- Richard Harter

[toc] | [prev] | [next] | [standalone]


#30561 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromTim Rentsch <txr@alumni.caltech.edu>
Date2013-01-22 21:29 -0800
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<kfn38xssc0i.fsf@x-alumni2.alumni.caltech.edu>
In reply to#30540
Ian Collins <ian-news@hotmail.com> writes:

>> [snip]
>>
> I just tried this code:
>
> #include <stdio.h>
>
> struct toto { const int i; const float f; const void *p; };
>
> struct toto foo(int i, float f, void *p)
> {
>   return (struct toto){i, f, p};
> }
>
> int main(void)
> {
>   float f = foo( 1,2,NULL).f;
> }
>
> and gcc (-Wall -std=c99 -pedantic) compiles it, but Sun c99 (which
> tends to be both strict and conforming) rejects it with one error:
>
> "x.c", line 7: left operand must be modifiable lvalue: op "="
>
> where line 7 is the function return.

I believe gcc has it right here.  Even the error message from
the Sun compiler suggests they were thinking of this like a
kind of assignment, which it certainly isn't in this case.

[toc] | [prev] | [next] | [standalone]


#30573 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2013-01-23 13:54 +0000
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<0.587c540b10d4d98feb70.20130123135415GMT.87zk000zug.fsf@bsb.me.uk>
In reply to#30561
Tim Rentsch <txr@alumni.caltech.edu> writes:

> Ian Collins <ian-news@hotmail.com> writes:
>
>>> [snip]
>>>
>> I just tried this code:
>>
>> #include <stdio.h>
>>
>> struct toto { const int i; const float f; const void *p; };
>>
>> struct toto foo(int i, float f, void *p)
>> {
>>   return (struct toto){i, f, p};
>> }
>>
>> int main(void)
>> {
>>   float f = foo( 1,2,NULL).f;
>> }
>>
>> and gcc (-Wall -std=c99 -pedantic) compiles it, but Sun c99 (which
>> tends to be both strict and conforming) rejects it with one error:
>>
>> "x.c", line 7: left operand must be modifiable lvalue: op "="
>>
>> where line 7 is the function return.
>
> I believe gcc has it right here.  Even the error message from
> the Sun compiler suggests they were thinking of this like a
> kind of assignment, which it certainly isn't in this case.

As you say elsewhere, the assignment-like nature of the return only
kicks in when the types differ, but even when it does, I'd take "is
converted as if by assignment" to mean that only the conversion and type
constraints of assignment are to be considered.  (The constraints being
important because they would, for example, prevent a function with type
'T *' returning a 'const T * value without a diagnostic).

More curious to me is that gcc (in conforming mode) permits this:

  struct toto { const int i; const float f; const void *p; };
   
  struct toto foo(int i, float f, void *p)
  {
    return (struct toto){i, f, p};
  }
   
  int bar(struct toto p) { return p.i; }
   
  int main(void)
  {
       return bar(foo(1, 2, 0));
  }

but 6.5.2.2 p2 says:

  "Each argument shall have a type such that its value may be assigned
  to an object with the unqualified version of the type of its
  corresponding parameter."

The phrase "unqualified version of the type" can't surely be intended to
mean the recursive removal of all type qualifiers.  Elsewhere it simply
means that the "top level" qualifiers are removed.  If that's the right
interpretation, the call to bar should be a constraint violation.

It looks like gcc is borrowing from C++ where argument passing is
defined to like initialisation (which I've always found that to be more
logical than C's assignment-like call semantics).  Anyway, either I'm
misreading something or gcc has missed something.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#30581 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-23 17:08 -0500
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<kdpn11$79e$1@dont-email.me>
In reply to#30573
On 1/23/2013 08:54, Ben Bacarisse wrote:
> Tim Rentsch <txr@alumni.caltech.edu> writes:
>
>> Ian Collins <ian-news@hotmail.com> writes:
>>
>>>> [snip]
>>>>
>>> I just tried this code:
>>>
>>> #include <stdio.h>
>>>
>>> struct toto { const int i; const float f; const void *p; };
>>>
>>> struct toto foo(int i, float f, void *p)
>>> {
>>>    return (struct toto){i, f, p};
>>> }
>>>
>>> int main(void)
>>> {
>>>    float f = foo( 1,2,NULL).f;
>>> }
>>>
>>> and gcc (-Wall -std=c99 -pedantic) compiles it, but Sun c99 (which
>>> tends to be both strict and conforming) rejects it with one error:
>>>
>>> "x.c", line 7: left operand must be modifiable lvalue: op "="
>>>
>>> where line 7 is the function return.
>>
>> I believe gcc has it right here.  Even the error message from
>> the Sun compiler suggests they were thinking of this like a
>> kind of assignment, which it certainly isn't in this case.
>
> As you say elsewhere, the assignment-like nature of the return only
> kicks in when the types differ, but even when it does, I'd take "is
> converted as if by assignment" to mean that only the conversion and type
> constraints of assignment are to be considered.  (The constraints being
> important because they would, for example, prevent a function with type
> 'T *' returning a 'const T * value without a diagnostic).
>
> More curious to me is that gcc (in conforming mode) permits this:
>
>    struct toto { const int i; const float f; const void *p; };
>
>    struct toto foo(int i, float f, void *p)
>    {
>      return (struct toto){i, f, p};
>    }
>
>    int bar(struct toto p) { return p.i; }
>
>    int main(void)
>    {
>         return bar(foo(1, 2, 0));
>    }
>
> but 6.5.2.2 p2 says:
>
>    "Each argument shall have a type such that its value may be assigned
>    to an object with the unqualified version of the type of its
>    corresponding parameter."
>
> The phrase "unqualified version of the type" can't surely be intended to
> mean the recursive removal of all type qualifiers.  Elsewhere it simply
> means that the "top level" qualifiers are removed.  If that's the right
> interpretation, the call to bar should be a constraint violation.
>

Why?  The result of the call to 'foo' yields a 'struct toto', which is 
not qualified (and also isn't an lvalue).

> It looks like gcc is borrowing from C++ where argument passing is
> defined to like initialisation (which I've always found that to be more
> logical than C's assignment-like call semantics).  Anyway, either I'm
> misreading something or gcc has missed something.
>

-- 
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily,"  -- Richard Harter

[toc] | [prev] | [next] | [standalone]


#30584 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromIan Collins <ian-news@hotmail.com>
Date2013-01-24 11:29 +1300
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<amb6hrFbhmbU2@mid.individual.net>
In reply to#30581
Shao Miller wrote:
> On 1/23/2013 08:54, Ben Bacarisse wrote:
>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>
>>> Ian Collins <ian-news@hotmail.com> writes:
>>>
>>>>> [snip]
>>>>>
>>>> I just tried this code:
>>>>
>>>> #include <stdio.h>
>>>>
>>>> struct toto { const int i; const float f; const void *p; };
>>>>
>>>> struct toto foo(int i, float f, void *p)
>>>> {
>>>>     return (struct toto){i, f, p};
>>>> }
>>>>
>>>> int main(void)
>>>> {
>>>>     float f = foo( 1,2,NULL).f;
>>>> }
>>>>
>>>> and gcc (-Wall -std=c99 -pedantic) compiles it, but Sun c99 (which
>>>> tends to be both strict and conforming) rejects it with one error:
>>>>
>>>> "x.c", line 7: left operand must be modifiable lvalue: op "="
>>>>
>>>> where line 7 is the function return.
>>>
>>> I believe gcc has it right here.  Even the error message from
>>> the Sun compiler suggests they were thinking of this like a
>>> kind of assignment, which it certainly isn't in this case.
>>
>> As you say elsewhere, the assignment-like nature of the return only
>> kicks in when the types differ, but even when it does, I'd take "is
>> converted as if by assignment" to mean that only the conversion and type
>> constraints of assignment are to be considered.  (The constraints being
>> important because they would, for example, prevent a function with type
>> 'T *' returning a 'const T * value without a diagnostic).
>>
>> More curious to me is that gcc (in conforming mode) permits this:
>>
>>     struct toto { const int i; const float f; const void *p; };
>>
>>     struct toto foo(int i, float f, void *p)
>>     {
>>       return (struct toto){i, f, p};
>>     }
>>
>>     int bar(struct toto p) { return p.i; }
>>
>>     int main(void)
>>     {
>>          return bar(foo(1, 2, 0));
>>     }
>>
>> but 6.5.2.2 p2 says:
>>
>>     "Each argument shall have a type such that its value may be assigned
>>     to an object with the unqualified version of the type of its
>>     corresponding parameter."
>>
>> The phrase "unqualified version of the type" can't surely be intended to
>> mean the recursive removal of all type qualifiers.  Elsewhere it simply
>> means that the "top level" qualifiers are removed.  If that's the right
>> interpretation, the call to bar should be a constraint violation.
>>
>
> Why?  The result of the call to 'foo' yields a 'struct toto', which is
> not qualified (and also isn't an lvalue).

I think Ben's point is the *parameter* value may be *assigned*, not the 
result of the expression.

I see Sun c99, which rejects the return in foo, also accepts bar.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#30586 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-23 18:26 -0500
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<kdprii$h72$1@dont-email.me>
In reply to#30584
On 1/23/2013 17:29, Ian Collins wrote:
> Shao Miller wrote:
>> On 1/23/2013 08:54, Ben Bacarisse wrote:
>>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>>
>>>> Ian Collins <ian-news@hotmail.com> writes:
>>>>
>>>>>> [snip]
>>>>>>
>>>>> I just tried this code:
>>>>>
>>>>> #include <stdio.h>
>>>>>
>>>>> struct toto { const int i; const float f; const void *p; };
>>>>>
>>>>> struct toto foo(int i, float f, void *p)
>>>>> {
>>>>>     return (struct toto){i, f, p};
>>>>> }
>>>>>
>>>>> int main(void)
>>>>> {
>>>>>     float f = foo( 1,2,NULL).f;
>>>>> }
>>>>>
>>>>> and gcc (-Wall -std=c99 -pedantic) compiles it, but Sun c99 (which
>>>>> tends to be both strict and conforming) rejects it with one error:
>>>>>
>>>>> "x.c", line 7: left operand must be modifiable lvalue: op "="
>>>>>
>>>>> where line 7 is the function return.
>>>>
>>>> I believe gcc has it right here.  Even the error message from
>>>> the Sun compiler suggests they were thinking of this like a
>>>> kind of assignment, which it certainly isn't in this case.
>>>
>>> As you say elsewhere, the assignment-like nature of the return only
>>> kicks in when the types differ, but even when it does, I'd take "is
>>> converted as if by assignment" to mean that only the conversion and type
>>> constraints of assignment are to be considered.  (The constraints being
>>> important because they would, for example, prevent a function with type
>>> 'T *' returning a 'const T * value without a diagnostic).
>>>
>>> More curious to me is that gcc (in conforming mode) permits this:
>>>
>>>     struct toto { const int i; const float f; const void *p; };
>>>
>>>     struct toto foo(int i, float f, void *p)
>>>     {
>>>       return (struct toto){i, f, p};
>>>     }
>>>
>>>     int bar(struct toto p) { return p.i; }
>>>
>>>     int main(void)
>>>     {
>>>          return bar(foo(1, 2, 0));
>>>     }
>>>
>>> but 6.5.2.2 p2 says:
>>>
>>>     "Each argument shall have a type such that its value may be assigned
>>>     to an object with the unqualified version of the type of its
>>>     corresponding parameter."
>>>
>>> The phrase "unqualified version of the type" can't surely be intended to
>>> mean the recursive removal of all type qualifiers.  Elsewhere it simply
>>> means that the "top level" qualifiers are removed.  If that's the right
>>> interpretation, the call to bar should be a constraint violation.
>>>
>>
>> Why?  The result of the call to 'foo' yields a 'struct toto', which is
>> not qualified (and also isn't an lvalue).
>
> I think Ben's point is the *parameter* value may be *assigned*, not the
> result of the expression.
>
> I see Sun c99, which rejects the return in foo, also accepts bar.
>

As in, a constraint violation against 6.5.16p2?  If so, why would that 
constraint apply?  There are still constraints in 6.5.16.1p1...  As 
asked elsethread, why pick out "modifiable" and not "lvalue"?  Do we 
need to worry about the constraints and semantics of 6.5.16.2?  Isn't 
backing up to 6.5.16 backing up too far?

-- 
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily,"  -- Richard Harter

[toc] | [prev] | [next] | [standalone]


#30591 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromIan Collins <ian-news@hotmail.com>
Date2013-01-24 14:03 +1300
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<ambfjhFbhmbU4@mid.individual.net>
In reply to#30586
Shao Miller wrote:
> On 1/23/2013 17:29, Ian Collins wrote:
>> Shao Miller wrote:
>>> On 1/23/2013 08:54, Ben Bacarisse wrote:
>>>>
>>>> but 6.5.2.2 p2 says:
>>>>
>>>>      "Each argument shall have a type such that its value may be assigned
>>>>      to an object with the unqualified version of the type of its
>>>>      corresponding parameter."
>>>>
>>>> The phrase "unqualified version of the type" can't surely be intended to
>>>> mean the recursive removal of all type qualifiers.  Elsewhere it simply
>>>> means that the "top level" qualifiers are removed.  If that's the right
>>>> interpretation, the call to bar should be a constraint violation.
>>>>
>>>
>>> Why?  The result of the call to 'foo' yields a 'struct toto', which is
>>> not qualified (and also isn't an lvalue).
>>
>> I think Ben's point is the *parameter* value may be *assigned*, not the
>> result of the expression.
>>
>> I see Sun c99, which rejects the return in foo, also accepts bar.
>>
>
> As in, a constraint violation against 6.5.16p2?

Yes.

> If so, why would that constraint apply?

Because of 6.5.2.2 p4, if you take the word "assigned" literally.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#30601 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-23 23:58 -0500
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<kdqf23$6ci$1@dont-email.me>
In reply to#30591
On 1/23/2013 20:03, Ian Collins wrote:
> Shao Miller wrote:
>> On 1/23/2013 17:29, Ian Collins wrote:
>>> Shao Miller wrote:
>>>> On 1/23/2013 08:54, Ben Bacarisse wrote:
>>>>>
>>>>> but 6.5.2.2 p2 says:
>>>>>
>>>>>      "Each argument shall have a type such that its value may be
>>>>> assigned
>>>>>      to an object with the unqualified version of the type of its
>>>>>      corresponding parameter."
>>>>>
>>>>> The phrase "unqualified version of the type" can't surely be
>>>>> intended to
>>>>> mean the recursive removal of all type qualifiers.  Elsewhere it
>>>>> simply
>>>>> means that the "top level" qualifiers are removed.  If that's the
>>>>> right
>>>>> interpretation, the call to bar should be a constraint violation.
>>>>>
>>>>
>>>> Why?  The result of the call to 'foo' yields a 'struct toto', which is
>>>> not qualified (and also isn't an lvalue).
>>>
>>> I think Ben's point is the *parameter* value may be *assigned*, not the
>>> result of the expression.
>>>
>>> I see Sun c99, which rejects the return in foo, also accepts bar.
>>>
>>
>> As in, a constraint violation against 6.5.16p2?
>
> Yes.
>
>> If so, why would that constraint apply?
>
> Because of 6.5.2.2 p4, if you take the word "assigned" literally.
>

Did you mean if you _don't_ take it literally?  I don't see "assigned" 
as a defined term, so I assume it's plain English.  The Committee 
Response for Defect Report #212 includes "assigned" when their code 
shows initialization.

Considering 6.9.1p11, does its use of "assigned" make sense if one of 
the parameters was 'const'-qualified?  I don't think so.

>> There are still constraints in 6.5.16.1p1...  As asked elsethread, why pick out "modifiable" and not "lvalue"?  Do we need to worry about the constraints and semantics of 6.5.16.2?  Isn't backing up to 6.5.16 backing up too far?

6.7.3p4:

   "The properties associated with qualified types are meaningful only 
for expressions that are lvalues.132)"

The "object" in "object with the unqualified version of the type of its 
corresponding parameter" seems to me to be a theoretical object and not 
an lvalue.  It's not the parameter, for example, because the parameter 
could have a different type.  So I don't grok a constraint violation 
against 6.5.16p2.

-- 
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily,"  -- Richard Harter

[toc] | [prev] | [next] | [standalone]


#30587 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2013-01-23 23:36 +0000
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<0.034ba52261503ab8aa1d.20130123233611GMT.877gn31nh0.fsf@bsb.me.uk>
In reply to#30584
Ian Collins <ian-news@hotmail.com> writes:

> Shao Miller wrote:
>> On 1/23/2013 08:54, Ben Bacarisse wrote:
>>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>>
>>>> Ian Collins <ian-news@hotmail.com> writes:
>>>>
>>>>>> [snip]
>>>>>>
>>>>> I just tried this code:
>>>>>
>>>>> #include <stdio.h>
>>>>>
>>>>> struct toto { const int i; const float f; const void *p; };
>>>>>
>>>>> struct toto foo(int i, float f, void *p)
>>>>> {
>>>>>     return (struct toto){i, f, p};
>>>>> }
>>>>>
>>>>> int main(void)
>>>>> {
>>>>>     float f = foo( 1,2,NULL).f;
>>>>> }
>>>>>
>>>>> and gcc (-Wall -std=c99 -pedantic) compiles it, but Sun c99 (which
>>>>> tends to be both strict and conforming) rejects it with one error:
>>>>>
>>>>> "x.c", line 7: left operand must be modifiable lvalue: op "="
>>>>>
>>>>> where line 7 is the function return.
>>>>
>>>> I believe gcc has it right here.  Even the error message from
>>>> the Sun compiler suggests they were thinking of this like a
>>>> kind of assignment, which it certainly isn't in this case.
>>>
>>> As you say elsewhere, the assignment-like nature of the return only
>>> kicks in when the types differ, but even when it does, I'd take "is
>>> converted as if by assignment" to mean that only the conversion and type
>>> constraints of assignment are to be considered.  (The constraints being
>>> important because they would, for example, prevent a function with type
>>> 'T *' returning a 'const T * value without a diagnostic).
>>>
>>> More curious to me is that gcc (in conforming mode) permits this:
>>>
>>>     struct toto { const int i; const float f; const void *p; };
>>>
>>>     struct toto foo(int i, float f, void *p)
>>>     {
>>>       return (struct toto){i, f, p};
>>>     }
>>>
>>>     int bar(struct toto p) { return p.i; }
>>>
>>>     int main(void)
>>>     {
>>>          return bar(foo(1, 2, 0));
>>>     }
>>>
>>> but 6.5.2.2 p2 says:
>>>
>>>     "Each argument shall have a type such that its value may be assigned
>>>     to an object with the unqualified version of the type of its
>>>     corresponding parameter."
>>>
>>> The phrase "unqualified version of the type" can't surely be intended to
>>> mean the recursive removal of all type qualifiers.  Elsewhere it simply
>>> means that the "top level" qualifiers are removed.  If that's the right
>>> interpretation, the call to bar should be a constraint violation.
>>>
>>
>> Why?  The result of the call to 'foo' yields a 'struct toto', which is
>> not qualified (and also isn't an lvalue).
>
> I think Ben's point is the *parameter* value may be *assigned*, not
> the result of the expression.

Yes, the types are fine but a value of stuct foo type can't be assigned
to an object of that type.  It reads as though parameter passing is,
essentially, assignment and whilst you can initialise a struct toto
object, you can't assign to one.

[I've just snipped a long and tedious paragraph trying to give some other
meaning to the phrasing, but since I don't buy it seems pointless to punt
it.]

> I see Sun c99, which rejects the return in foo, also accepts bar.

Interesting.  Is it also a C++ compiler when given other options?  C++
uses initialisation semantics for parameter passing, so it might be an
accident.  Of course it could just be that the gcc and Sun c99 authors
are just better as reading standards!

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#30590 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromIan Collins <ian-news@hotmail.com>
Date2013-01-24 13:55 +1300
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<ambf3jFbhmbU3@mid.individual.net>
In reply to#30587
Ben Bacarisse wrote:
> Ian Collins <ian-news@hotmail.com> writes:
>
>> I see Sun c99, which rejects the return in foo, also accepts bar.
>
> Interesting.  Is it also a C++ compiler when given other options?  C++
> uses initialisation semantics for parameter passing, so it might be an
> accident.  Of course it could just be that the gcc and Sun c99 authors
> are just better as reading standards!

No, I'm sure the compilers have a different front end, their error 
messages have a different style.  For example with

   struct toto t;
   t = foo( 1,2,NULL);

c99 reports

"x.c", line 17: left operand must be modifiable lvalue: op "="

while CC reports

"x.c", line 16: Error: t must be initialized.
"x.c", line 17: Error: toto has a const member i and cannot be assigned.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#30595 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2013-01-24 02:44 +0000
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<0.2f9d39b612ab01506709.20130124024406GMT.87txq7z4eh.fsf@bsb.me.uk>
In reply to#30590
Ian Collins <ian-news@hotmail.com> writes:

> Ben Bacarisse wrote:
>> Ian Collins <ian-news@hotmail.com> writes:
>>
>>> I see Sun c99, which rejects the return in foo, also accepts bar.
>>
>> Interesting.  Is it also a C++ compiler when given other options?  C++
>> uses initialisation semantics for parameter passing, so it might be an
>> accident.  Of course it could just be that the gcc and Sun c99 authors
>> are just better as reading standards!
>
> No, I'm sure the compilers have a different front end, their error
> messages have a different style.

Ah, right.  Thanks.  Just another data point: Comeau's online C99
compiler accepts it (both the return and the call of 'bar').

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#30602 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromTim Rentsch <txr@alumni.caltech.edu>
Date2013-01-23 21:39 -0800
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<kfn622n6sxu.fsf@x-alumni2.alumni.caltech.edu>
In reply to#30573
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> Tim Rentsch <txr@alumni.caltech.edu> writes:
>
>> Ian Collins <ian-news@hotmail.com> writes:
>>
>>>> [snip]
>>>>
>>> I just tried this code:
>>>
>>> #include <stdio.h>
>>>
>>> struct toto { const int i; const float f; const void *p; };
>>>
>>> struct toto foo(int i, float f, void *p)
>>> {
>>>   return (struct toto){i, f, p};
>>> }
>>>
>>> int main(void)
>>> {
>>>   float f = foo( 1,2,NULL).f;
>>> }
>>>
>>> and gcc (-Wall -std=c99 -pedantic) compiles it, but Sun c99
>>> (which tends to be both strict and conforming) rejects it
>>> with one error:
>>>
>>> "x.c", line 7: left operand must be modifiable lvalue: op "="
>>>
>>> where line 7 is the function return.
>>
>> I believe gcc has it right here.  Even the error message from
>> the Sun compiler suggests they were thinking of this like a
>> kind of assignment, which it certainly isn't in this case.
>
> As you say elsewhere, the assignment-like nature of the return
> only kicks in when the types differ, but even when it does, I'd
> take "is converted as if by assignment" to mean that only the
> conversion and type constraints of assignment are to be
> considered.

I assume you mean >simple< assignment in the last part of that
sentence.

> (The constraints being important because they would, for example,
> prevent a function with type 'T *' returning a 'const T * value
> without a diagnostic).

I expect you're right if we're talking about what meaning was
intended.  However, just in terms of what is written, it's hard
to make that stand up considering other parts of the Standard.
In both of the other two cases (those being function arguments
and initializer expressions) where there are similar concerns,
the limiting constraints are identified explicitly.  So their
absence for 'return' stands out -- exceptio probat regulam in
casibus non exceptis, and all that.  In all likelihood though
that was just an oversight, and a reasonable inference for
purposes of comp.lang.c is the constraints of simple assignment
are meant to apply.


> More curious to me is that gcc (in conforming mode) permits
> this:
>
>   struct toto { const int i; const float f; const void *p; };
>    
>   struct toto foo(int i, float f, void *p)
>   {
>     return (struct toto){i, f, p};
>   }
>    
>   int bar(struct toto p) { return p.i; }
>    
>   int main(void)
>   {
>        return bar(foo(1, 2, 0));
>   }
>
> but 6.5.2.2 p2 says:
>
>   "Each argument shall have a type such that its value may be
>   assigned to an object with the unqualified version of the
>   type of its corresponding parameter."
>
> The phrase "unqualified version of the type" can't surely be
> intended to mean the recursive removal of all type qualifiers.
> Elsewhere it simply means that the "top level" qualifiers are
> removed.  If that's the right interpretation, the call to bar
> should be a constraint violation.  
>
> [speculation about why gcc acts as it does]  Anyway, either
> I'm misreading something or gcc has missed something.

Yes, your analysis looks spot on.

Here though I think we're looking at the flip side of the coin.
That is, this case also represents an oversight, only here the
result is more restrictive rather than less restrictive.  It
seems unlikely that this tiny incompatibility would knowingly be
imposed just for function arguments, especially since it is
clearly a useful capability to support, and initialization
semantics are so intuitively natural.  I expect it was just an
accident of how the writing happened -- provisions were put in to
handle the common cases, and this one unusual case fell through
the cracks.  (And you can see how someone reading the rules for
function arguments might gloss over the distinction between the
two ways "unqualified version of the type" might be read.)  In
a way it's good to see that common sense has prevailed (ie, in
gcc, and also I think another compiler was mentioned in another
posting) about what was meant here.  All that remains is making
sure what's in the Standard gets updated to reflect that.

[toc] | [prev] | [next] | [standalone]


#30603 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-24 00:54 -0500
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<kdqia9$j95$1@dont-email.me>
In reply to#30602
On 1/24/2013 00:39, Tim Rentsch wrote:
>
> Here though I think we're looking at the flip side of the coin.
> That is, this case also represents an oversight, only here the
> result is more restrictive rather than less restrictive.  It
> seems unlikely that this tiny incompatibility would knowingly be
> imposed just for function arguments, especially since it is
> clearly a useful capability to support, and initialization
> semantics are so intuitively natural.  I expect it was just an
> accident of how the writing happened -- provisions were put in to
> handle the common cases, and this one unusual case fell through
> the cracks.  (And you can see how someone reading the rules for
> function arguments might gloss over the distinction between the
> two ways "unqualified version of the type" might be read.)  In
> a way it's good to see that common sense has prevailed (ie, in
> gcc, and also I think another compiler was mentioned in another
> posting) about what was meant here.  All that remains is making
> sure what's in the Standard gets updated to reflect that.
>

I don't see how you can reconcile a 'const'-qualified parameter with 
these two paragraphs of 6.9.1, if the "modifiable lvalue" from 6.5.16p2 
has any bearing:

   "10 On entry to the function, the size expressions of each variably 
modified parameter are evaluated and the value of each argument 
expression is converted to the type of the corresponding parameter as if 
by assignment. (Array expressions and function designators as arguments 
were converted to pointers before the call.)

    11 After all parameters have been assigned, the compound statement 
that constitutes the body of the function definition is executed."

-- 
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily,"  -- Richard Harter

[toc] | [prev] | [next] | [standalone]


#30617 — Re: Initializing a malloc'ed struct whose fields are const with run-time values

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2013-01-24 17:56 +0000
SubjectRe: Initializing a malloc'ed struct whose fields are const with run-time values
Message-ID<0.1827e26976fc5b0b81cf.20130124175614GMT.87fw1qzcqp.fsf@bsb.me.uk>
In reply to#30602
Tim Rentsch <txr@alumni.caltech.edu> writes:

> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
<snip>
>> More curious to me is that gcc (in conforming mode) permits
>> this:
>>
>>   struct toto { const int i; const float f; const void *p; };
>>    
>>   struct toto foo(int i, float f, void *p)
>>   {
>>     return (struct toto){i, f, p};
>>   }
>>    
>>   int bar(struct toto p) { return p.i; }
>>    
>>   int main(void)
>>   {
>>        return bar(foo(1, 2, 0));
>>   }
>>
>> but 6.5.2.2 p2 says:
>>
>>   "Each argument shall have a type such that its value may be
>>   assigned to an object with the unqualified version of the
>>   type of its corresponding parameter."
>>
>> The phrase "unqualified version of the type" can't surely be
>> intended to mean the recursive removal of all type qualifiers.
>> Elsewhere it simply means that the "top level" qualifiers are
>> removed.  If that's the right interpretation, the call to bar
>> should be a constraint violation.  
>>
>> [speculation about why gcc acts as it does]  Anyway, either
>> I'm misreading something or gcc has missed something.
>
> Yes, your analysis looks spot on.
>
> Here though I think we're looking at the flip side of the coin.
> That is, this case also represents an oversight, only here the
> result is more restrictive rather than less restrictive.  It
> seems unlikely that this tiny incompatibility would knowingly be
> imposed just for function arguments, especially since it is
> clearly a useful capability to support, and initialization
> semantics are so intuitively natural.  I expect it was just an
> accident of how the writing happened -- provisions were put in to
> handle the common cases, and this one unusual case fell through
> the cracks.  (And you can see how someone reading the rules for
> function arguments might gloss over the distinction between the
> two ways "unqualified version of the type" might be read.)  In
> a way it's good to see that common sense has prevailed (ie, in
> gcc, and also I think another compiler was mentioned in another
> posting) about what was meant here.  All that remains is making
> sure what's in the Standard gets updated to reflect that.

One option would be to define function calling in terms of
initialization but that may have unforeseen consequences.  Something like

  "Each argument shall have a type such that its value may be used as a
  single expression initializer of its corresponding parameter."

and later:

  "In preparing for the call to a function, the arguments are evaluated,
  and each parameter is initialized using the value of the corresponding
  argument."

At first glance, all the right wording is there, at least for scalar
types:

  11 The initializer for a scalar shall be a single expression,
     optionally enclosed in braces. The initial value of the object is
     that of the expression (after conversion); the same type
     constraints and conversions as for simple assignment apply, taking
     the type of the scalar to be the unqualified version of its
     declared type."

but then paragraph 13 surprised me a little:

  13 The initializer for a structure or union object that has automatic
     storage duration shall be either an initializer list as described
     below, or a single expression that has compatible structure or
     union type. In the latter case, the initial value of the object,
     including unnamed members, is that of the expression.

This is from the "semantics" section, so for structure and union types
there is no constraint violation if the types are not compatible.
Whilst this is an odd anomaly of initialization, it's probably
unacceptable for function calls -- you really want to mandate a
diagnostic when the types don't match.

Also, on a side issue, the wording about disregarding the type's
qualifiers is also missing.  Obviously

  const struct s = (struct s){0};

is supposed to be permitted, so is "struct s" a "compatible structure or
union type"?  Probably.  It's not a compatible type, but the extra words
might be there to suggest that it's only the structural part that is to
be considered.  I'd rather that were more explicit, though.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →

Back to top | Article view | comp.lang.c


csiph-web