Go Back   Rhinocerus > Newsgroup > Newsgroup comp.lang.c

Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old 03-10-2012, 12:09 AM
Joe keane
Guest
 
Posts: n/a
Default i think i found

How about this?

int f(int x)
{
int a[2];
int *p;

p = &a[0];
*p = 2;
++p;
*p = 3;
/* printf("%d %d\n", a[0], a[1]); */
}

That pretty much has to work, right?

So what's the deal with arrays of arrays?
Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

  #2 (permalink)  
Old 03-10-2012, 12:23 AM
Ian Collins
Guest
 
Posts: n/a
Default Re: i think i found

On 03/10/12 02:09 PM, Joe keane wrote:
> How about this?
>
> int f(int x)
> {
> int a[2];
> int *p;
>
> p =&a[0];
> *p = 2;
> ++p;
> *p = 3;
> /* printf("%d %d\n", a[0], a[1]); */
> }
>
> That pretty much has to work, right?


Why shouldn't it?


> So what's the deal with arrays of arrays?


Two for $10.

--
Ian Collins
Reply With Quote
  #3 (permalink)  
Old 03-10-2012, 10:13 AM
nick_keighley_nospam@hotmail.com
Guest
 
Posts: n/a
Default Re: i think i found

On Saturday, March 10, 2012 1:09:33 AM UTC, Joe keane wrote:
> How about this?
>
> int f(int x)
> {
> int a[2];
> int *p;
>
> p = &a[0];
> *p = 2;
> ++p;
> *p = 3;
> /* printf("%d %d\n", a[0], a[1]); */
> }
>
> That pretty much has to work, right?
>
> So what's the deal with arrays of arrays?


what?
Reply With Quote
  #4 (permalink)  
Old 03-10-2012, 04:17 PM
Barry Schwarz
Guest
 
Posts: n/a
Default Re: i think i found

On Mar 9, 7:09*pm, j...@panix.com (Joe keane) wrote:
> How about this?
>
> * * int f(int x)
> * * {
> * * * * int a[2];
> * * * * int *p;
>
> * * * * p = &a[0];
> * * * * *p = 2;
> * * * * ++p;
> * * * * *p = 3;
> * * * * /* printf("%d %d\n", a[0], a[1]); */
> * * }
>
> That pretty much has to work, right?


No it does not. The function fails to return an int as promised in
the declaration. I don't remember whether this is undefined behavior
or a constraint violation.

>
> So what's the deal with arrays of arrays?


Since your sample code does not have any arrays of arrays, we have no
idea what your question is. Did you perchance mean something like

int f(int x)
{
int a[4][3];
int (*p)[3];

p = &a[0];
(*p)[1] = 2;
++p;
(*p)[2] = 3;
/* printf("%d %d\n", a[0][1], a[1][2]); */
return 0;
}
Reply With Quote
  #5 (permalink)  
Old 03-10-2012, 11:22 PM
pete
Guest
 
Posts: n/a
Default Re: i think i found

Barry Schwarz wrote:
>
> On Mar 9, 7:09 pm, j...@panix.com (Joe keane) wrote:
> > How about this?
> >
> > int f(int x)
> > {
> > int a[2];
> > int *p;
> >
> > p = &a[0];
> > *p = 2;
> > ++p;
> > *p = 3;
> > /* printf("%d %d\n", a[0], a[1]); */
> > }
> >
> > That pretty much has to work, right?

>
> No it does not. The function fails to return an int as promised in
> the declaration. I don't remember whether this is undefined behavior
> or a constraint violation.


Prior to C99, these words:

ISO/IEC 9899: 1990
6.6.6.4 The return statement

A function may have any number of return statements,
with and without expressions.

If a return statement without an expression is executed,
and the value of the function call is used by the caller,
the behavior is undefined.
Reaching the } that terminates a function is
equivalent to executing a return statement without an expression.

suggest that the use of the above function was defined in C90,
as long as the code didn't use the return value.

Both C99 and n1570, only have this much to say on this matter:

A function may have any number of return statements.



> > So what's the deal with arrays of arrays?

>
> Since your sample code does not have any arrays of arrays, we have no
> idea what your question is. Did you perchance mean something like
>
> int f(int x)
> {
> int a[4][3];
> int (*p)[3];
>
> p = &a[0];
> (*p)[1] = 2;
> ++p;
> (*p)[2] = 3;
> /* printf("%d %d\n", a[0][1], a[1][2]); */
> return 0;
> }


I think that leaving the printf statement commented out
is a little bit funny.

--
pete
Reply With Quote
  #6 (permalink)  
Old 03-11-2012, 12:14 AM
James Kuyper
Guest
 
Posts: n/a
Default Re: i think i found

On 03/10/2012 07:22 PM, pete wrote:
> Barry Schwarz wrote:

....
> Prior to C99, these words:
>
> ISO/IEC 9899: 1990
> 6.6.6.4 The return statement
>
> A function may have any number of return statements,
> with and without expressions.
>
> If a return statement without an expression is executed,
> and the value of the function call is used by the caller,
> the behavior is undefined.
> Reaching the } that terminates a function is
> equivalent to executing a return statement without an expression.
>
> suggest that the use of the above function was defined in C90,
> as long as the code didn't use the return value.
>
> Both C99 and n1570, only have this much to say on this matter:
>
> A function may have any number of return statements.


They didn't change that aspect of C in C99, they only changed the way it
was expressed.
6.9.1p12: "If the } that terminates a function is reached, and the value
of the function call is used by the caller, the behavior is undefined.".
--
James Kuyper
Reply With Quote
  #7 (permalink)  
Old 03-11-2012, 01:59 AM
pete
Guest
 
Posts: n/a
Default Re: i think i found

James Kuyper wrote:
>
> On 03/10/2012 07:22 PM, pete wrote:
> > Barry Schwarz wrote:

> ...
> > Prior to C99, these words:
> >
> > ISO/IEC 9899: 1990
> > 6.6.6.4 The return statement
> >
> > A function may have any number of return statements,
> > with and without expressions.
> >
> > If a return statement without an expression is executed,
> > and the value of the function call is used by the caller,
> > the behavior is undefined.
> > Reaching the } that terminates a function is
> > equivalent to executing a return statement without an expression.
> >
> > suggest that the use of the above function was defined in C90,
> > as long as the code didn't use the return value.
> >
> > Both C99 and n1570, only have this much to say on this matter:
> >
> > A function may have any number of return statements.

>
> They didn't change that aspect of C in C99,
> they only changed the way it was expressed.
> 6.9.1p12: "If the } that terminates a function is reached,
> and the value
> of the function call is used by the caller,
> the behavior is undefined.".


Thank you.
n1570 is the same way.

--
pete
Reply With Quote
  #8 (permalink)  
Old 03-11-2012, 06:35 PM
Joe keane
Guest
 
Posts: n/a
Default Re: i think i found

In article <ea3cda64-a914-4f34-ba2a-59df5fb9fc93@m13g2000yqi.googlegroups.com>,
Barry Schwarz <schwarz45@yahoo.com> wrote:
>Since your sample code does not have any arrays of arrays, we have no
>idea what your question is.


OK

int f(int x)
{
int a[2][2];
int *p;

p = &a[0][0];
*p = 1;
p += 2;
*p = 2;
--p;
*p = 3;
p += 2;
*p = 4;
/* printf(...); */
return 0;
}
Reply With Quote
  #9 (permalink)  
Old 03-11-2012, 07:06 PM
Keith Thompson
Guest
 
Posts: n/a
Default Re: i think i found

jgk@panix.com (Joe keane) writes:
> In article <ea3cda64-a914-4f34-ba2a-59df5fb9fc93@m13g2000yqi.googlegroups.com>,
> Barry Schwarz <schwarz45@yahoo.com> wrote:
>>Since your sample code does not have any arrays of arrays, we have no
>>idea what your question is.

>
> OK
>
> int f(int x)
> {
> int a[2][2];
> int *p;
>
> p = &a[0][0];
> *p = 1;
> p += 2;
> *p = 2;
> --p;
> *p = 3;
> p += 2;
> *p = 4;
> /* printf(...); */
> return 0;
> }


Great, you've posted some more code. Did you want to say something
about it? Your subject header is "i think i found". What exactly do
you think you've found?

I'm sure the point you're making is clear to you, but you're not
conveying it well to the rest of us.

As for the code you posted, its behavior is undefined. "p" is an "int*"
that's initialized to point to element 0 of a 2-element array a[0]
(which happens to be an element of a larger array). "p += 2" causes it
to point just past the last element of the array a[0], which is ok. But
the "*p = 2;" assigns a value past the end of that array, which has
undefined behavior.

N1570 section J.2 has a (non-normative) list of undefined behaviors, one
of which is:

An array subscript is out of range, even if an object is apparently
accessible with the given subscript (as in the lvalue expression
a[1][7] given the declaration int a[4][5]) (6.5.6).

So what was your question?

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Reply With Quote
  #10 (permalink)  
Old 03-12-2012, 04:29 PM
Joe keane
Guest
 
Posts: n/a
Default Re: i think i found

In article <4F5BF051.303D@mindspring.com>,
pete <pfiland@mindspring.com> wrote:
>Prior to C99, these words:

[...]
>suggest that the use of the above function was defined in C90,
>as long as the code didn't use the return value.


I slip into C78.
Reply With Quote
  #11 (permalink)  
Old 03-13-2012, 07:27 PM
Joe keane
Guest
 
Posts: n/a
Default Re: i think i found

In article <lnipiaewcj.fsf@nuthaus.mib.org>,
Keith Thompson <kst-u@mib.org> wrote:
> An array subscript is out of range, even if an object is apparently
> accessible with the given subscript (as in the lvalue expression
> a[1][7] given the declaration int a[4][5]) (6.5.6).


I didn't use 'array subscript' at all!

It is fine that in a "a[i][j]" syntax people can check both subsctipts
rather than the offset. But it's rather oblique about whether you can
increment a 'int *' pointer, e.g. from &a[0][4] to &a[1][0]. It would
be kind of sad if this didn't work right. It doesn't overtly address
the point.
Reply With Quote
  #12 (permalink)  
Old 03-13-2012, 09:25 PM
Keith Thompson
Guest
 
Posts: n/a
Default Re: i think i found

jgk@panix.com (Joe keane) writes:
> In article <lnipiaewcj.fsf@nuthaus.mib.org>,
> Keith Thompson <kst-u@mib.org> wrote:
>> An array subscript is out of range, even if an object is apparently
>> accessible with the given subscript (as in the lvalue expression
>> a[1][7] given the declaration int a[4][5]) (6.5.6).

>
> I didn't use 'array subscript' at all!
>
> It is fine that in a "a[i][j]" syntax people can check both subsctipts
> rather than the offset. But it's rather oblique about whether you can
> increment a 'int *' pointer, e.g. from &a[0][4] to &a[1][0]. It would
> be kind of sad if this didn't work right. It doesn't overtly address
> the point.


The array subscript operation is defined in terms of pointer
arithmetic; E1[E2] is by definition identical to (*((E1)+(E2))).
It follows from that that your example's behavior is undefined.

In practice, it's likely to "work", but a compiler is free to generate
code assuming that the indices do not exceed the declared bounds of the
array.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Reply With Quote
  #13 (permalink)  
Old 03-14-2012, 10:34 PM
Joe keane
Guest
 
Posts: n/a
Default Re: i think i found

In article <lnk42ocf5l.fsf@nuthaus.mib.org>,
Keith Thompson <kst-u@mib.org> wrote:
>The array subscript operation is defined in terms of pointer
>arithmetic; E1[E2] is by definition identical to (*((E1)+(E2))).


What is 'array subscript'?

An array type is contiguous. What does that mean?

int f(int t)
{
int a[3];
int *p;

p = a;
++p;
*p = 1;
}

As we expect, this stores in a consistent location.

An array of arrays is contiguous. It doesn't say only the last
dimension is contiguous, all of them are. So then the whole thing is.
And we have 'sizeof' to prove it.

int g(int t)
{
int b[4][5];
int *p;

p = *a;
p += 4;
*p = 4;
p += 2;
*p = 6;
}

If it breaks on the second one, then the array is not 'contiguous'.

The compiler can't change it to 'int b[4][8];' because that's not
'contiguous' the way the programmer wanted.

I'm just using an 'int *' here. It has to work the same as any other
'int *', pointing to the stack, from malloc, or whatever. I don't think
it can 'remember' a bunch of extra stuff.

>It follows from that that your example's behavior is undefined.


unclear
Reply With Quote
  #14 (permalink)  
Old 03-14-2012, 11:38 PM
Eric Sosman
Guest
 
Posts: n/a
Default Re: i think i found

On 3/14/2012 7:34 PM, Joe keane wrote:
> In article<lnk42ocf5l.fsf@nuthaus.mib.org>,
> Keith Thompson<kst-u@mib.org> wrote:
>> The array subscript operation is defined in terms of pointer
>> arithmetic; E1[E2] is by definition identical to (*((E1)+(E2))).

>
> What is 'array subscript'?


The subject of Section 6.5.2.1 of a certain International
Standard.

> An array type is contiguous. What does that mean?


The word "contiguous" is given no special meaning by the
International Standard mentioned above, so we must assume that
the Standard uses the word in accordance with its meaning in
English. There is no formal definition of English, nor any
authority that can be called "authoritative" (all dictionaries,
lexicons, grammars, and the like being merely derivative works),
but one studious observer of English offers

con-tig-u-ous adj [L /contiguus/, fr /contingere/ to
have contact with] 1 : being in actual contact :
TOUCHING 2 : ADJOINING 3 : next or near in time or
sequence *syn* see ADJACENT

For arrays as described in Section 6.2.5 paragraph 20 of the
aforementioned aforementioned Standard, I think we can discard
meaning (1) and imagine that meanings (2) and/or (3) are intended.

> As we expect, this stores in a consistent location.
>
> An array of arrays is contiguous. It doesn't say only the last
> dimension is contiguous, all of them are. So then the whole thing is.
> And we have 'sizeof' to prove it.
>
> int g(int t)
> {
> int b[4][5];
> int *p;
>
> p = *a;
> p += 4;
> *p = 4;
> p += 2;
> *p = 6;
> }
>
> If it breaks on the second one, then the array is not 'contiguous'.


It "breaks" because it doesn't even compile. More often
than I'd like, my own incomplete editing of what started as an
English sentence turns it into garbage; has something similar
happened here?

> unclear


You betcha.

--
Eric Sosman
esosman@ieee-dot-org.invalid
Reply With Quote
  #15 (permalink)  
Old 03-16-2012, 12:03 AM
Tim Rentsch
Guest
 
Posts: n/a
Default Re: i think i found

jgk@panix.com (Joe keane) writes:

> In article <lnk42ocf5l.fsf@nuthaus.mib.org>,
> Keith Thompson <kst-u@mib.org> wrote:
>>The array subscript operation is defined in terms of pointer
>>arithmetic; E1[E2] is by definition identical to (*((E1)+(E2))).

>
> What is 'array subscript'?
>
> An array type is contiguous. What does that mean?
>
> int f(int t)
> {
> int a[3];
> int *p;
>
> p = a;
> ++p;
> *p = 1;
> }
>
> As we expect, this stores in a consistent location.
>
> An array of arrays is contiguous. It doesn't say only the last
> dimension is contiguous, all of them are. So then the whole
> thing is. And we have 'sizeof' to prove it.
>
> int g(int t)
> {
> int b[4][5];
> int *p;
>
> p = *b; // [corrected from p = *a;]
> p += 4;
> *p = 4;
> p += 2;
> *p = 6;
> }
>
> If it breaks on the second one, then the array is not 'contiguous'.
>
> The compiler can't change it to 'int b[4][8];' because that's not
> 'contiguous' the way the programmer wanted.


Yes, the individual elements are contiguous. However, that
fact alone is not enough to guarantee that this sort of
"cross-subarray-bounds" indexing will work.


> I'm just using an 'int *' here. It has to work the same as any
> other 'int *', pointing to the stack, from malloc, or whatever.


In fact that's not right, according to remarks in the Standard
and also, IIRC, some Defect Reports. Sad but true.

> I don't think it can 'remember' a bunch of extra stuff.


It can, or at least act as though it does in some ways. The
low-order bits are somewhat murky, but the high-order bit is ONE.


>>It follows from that that your example's behavior is undefined.

>
> unclear


The Standard does make it clear that some cases of indexing
outside the bounds of a single subarray transgress into
undefined behavior, and it is likely that the code above
falls under the cases intended for that.

The Standard is _not_ clear about exactly where the boundaries
are as to what is defined and what is undefined in such
cases, and that has led to a lot of arguments in the
newsgroups about which is which. However, for simple
cases like the one shown above, I believe the evidence
that they are meant to be undefined behavior is pretty
convincing.

If you care, an assignment (or initialization) like

int *p = (int*) &b;

is more likely to work as you expect (ie, and be defined
behavior) for the "cross-subarray-bounds" indexing like
that shown in the example. So that might be a good way
to respond to this issue.
Reply With Quote
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off




All times are GMT. The time now is 12:15 AM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.