doubt in USING POINTERS

J

Joe Wright

Wojtek said:
Still, 6.2.4p1 says that every object has a storage duration and that only
three storage durations exist to choose from. The list of cases in 6.2.4 is
not exactly exhaustive -- it doesn't cover compound literals, either. You
have to go to 6.5.2.5p6 to find out how compound literals fit into the
scheme of the three defined storage durations.

Since the storage duration of the result of a function isn't specified
anywhere, the safest choice seems to be to assume that it's unspecified; but
6.2.4p1 seems to imply that it must be one of the three anyway.
The return value of a function is not an object. It has no storage
duration.
Therefore, the accessibility of the returned structure is controlled
only by the statement that which says that it can't be safely accessed
after the next sequence point. I'd prefer a positive statement that it
can be safely accessed, until the next sequence point.

Agreed.

BTW It just occured to me that structure assignment has the same problem --
or even worse, because as far as I can tell, the standard does not say
anywhere that you can't modify the value or access it after the next
sequence point:

struct { int arr[2]; } a, b;

( a = b ).arr[0] = 6;
int *p = ( a = b ).arr;
*p = 7;
Again, ( a = b ) is a value, not an object. Knowing that a.arr and b.arr
are in different structures, which do you assign 6 to? Which do you
expect p to point to?
In C++, the result of a simple assignment is an lvalue, and it's clear that
(a=b).arr[0] refers to a.arr[0]. In C, if feels more appropriate for the
result of a=b to be a third copy of the structure value, distinct from a and
b. But the standard doesn't say that anywhere, does it?...
 
W

Wojtek Lerch

Joe Wright said:
The return value of a function is not an object. It has no storage
duration.

Did you read my reply to your previous post? Did you take a look at the
places in the standard that I pointed you to?

The result of a function call is a value. In the case in question, the type
of this value is a structure containing an array. Applying the . operator
to it produces a value (still not an lvalue) whose type is array of int.
But then this array value decays to a pointer to the first element of the
array. Since the only thing a pointer can point to is an object, the array
elements must be objects, too. If you believe that some words in the
standard say that they're not objects, or that the array value does not
decay to a pointer, please tell me where to find those words.

....
struct { int arr[2]; } a, b;

( a = b ).arr[0] = 6;
int *p = ( a = b ).arr;
*p = 7;

Again, ( a = b ) is a value, not an object. Knowing that a.arr and b.arr
are in different structures, which do you assign 6 to? Which do you
expect p to point to?

*I* wouldn't expect it to point to either of them, but the standard says
nothing about it. That's the problem.
 
W

Wojtek Lerch

James Kuyper said:
"Wojtek Lerch" <[email protected]> wrote in message only

A return value isn't an object.

No, it's a value. In the case in question, it's a structure containing an
array. Trouble is, in the expression fun().arr[0] the array, even though
it's not an lvalue, decays to a pointer to the initial element of the array
(6.3.2.1p3). If that element is not an object, what exactly does the
pointer point to?
 
L

lawrence.jones

In comp.std.c Wojtek Lerch said:
BTW It just occured to me that structure assignment has the same problem --
or even worse, because as far as I can tell, the standard does not say
anywhere that you can't modify the value or access it after the next
sequence point:

See 6.5.16p4.

-Larry Jones

I hope Mom and Dad didn't rent out my room. -- Calvin
 
J

Joe Wright

Wojtek said:
Joe Wright said:
The return value of a function is not an object. It has no storage
duration.

Did you read my reply to your previous post? Did you take a look at the
places in the standard that I pointed you to?

The result of a function call is a value. In the case in question, the type
of this value is a structure containing an array. Applying the . operator
to it produces a value (still not an lvalue) whose type is array of int.
But then this array value decays to a pointer to the first element of the
array. Since the only thing a pointer can point to is an object, the array
elements must be objects, too. If you believe that some words in the
standard say that they're not objects, or that the array value does not
decay to a pointer, please tell me where to find those words.

...
struct { int arr[2]; } a, b;

( a = b ).arr[0] = 6;
int *p = ( a = b ).arr;
*p = 7;

Again, ( a = b ) is a value, not an object. Knowing that a.arr and b.arr
are in different structures, which do you assign 6 to? Which do you
expect p to point to?

*I* wouldn't expect it to point to either of them, but the standard says
nothing about it. That's the problem.

There are many things the Standard does not address. Too bad. If you
agree that a structure value is not an object, then an array value
within that structure value is not an object either. Values don't have
addresses, storage durations, or other attributes associated with
objects except type.
 
G

Gabriel Dos Reis

[...]

| > > > struct { int arr[2]; } a, b;
| > > >
| > > > ( a = b ).arr[0] = 6;
| > > > int *p = ( a = b ).arr;
| > > > *p = 7;
| > >
| > > Again, ( a = b ) is a value, not an object. Knowing that a.arr and b.arr
| > > are in different structures, which do you assign 6 to? Which do you
| > > expect p to point to?
| >
| > *I* wouldn't expect it to point to either of them, but the standard says
| > nothing about it. That's the problem.
|
| There are many things the Standard does not address. Too bad. If you
| agree that a structure value is not an object, then an array value
| within that structure value is not an object either. Values don't have
| addresses, storage durations, or other attributes associated with
| objects except type.

Do you agree that (a = b).arr[0] is an lvalue?

-- Gaby
 
J

j

Wojtek Lerch said:
unspecified;

Did you read my reply to your previous post? Did you take a look at the
places in the standard that I pointed you to?

The result of a function call is a value. In the case in question, the type
of this value is a structure containing an array. Applying the . operator
to it produces a value (still not an lvalue) whose type is array of int.
But then this array value decays to a pointer to the first element of the
array.

Only under c99. In c90 it doesn't decay at all.
Since the only thing a pointer can point to is an object, the array
elements must be objects, too. If you believe that some words in the
standard say that they're not objects, or that the array value does not
decay to a pointer, please tell me where to find those words.

lawerence jones is the one who pointed this out. Since I don't have a copy
of the c90
standard he would have to point out the relevant sections.
...
struct { int arr[2]; } a, b;

( a = b ).arr[0] = 6;
int *p = ( a = b ).arr;
*p = 7;

Again, ( a = b ) is a value, not an object. Knowing that a.arr and b.arr
are in different structures, which do you assign 6 to? Which do you
expect p to point to?

*I* wouldn't expect it to point to either of them, but the standard says
nothing about it. That's the problem.
 
J

Joe Wright

Gabriel said:
[...]

| > > > struct { int arr[2]; } a, b;
| > > >
| > > > ( a = b ).arr[0] = 6;
| > > > int *p = ( a = b ).arr;
| > > > *p = 7;
| > >
| > > Again, ( a = b ) is a value, not an object. Knowing that a.arr and b.arr
| > > are in different structures, which do you assign 6 to? Which do you
| > > expect p to point to?
| >
| > *I* wouldn't expect it to point to either of them, but the standard says
| > nothing about it. That's the problem.
|
| There are many things the Standard does not address. Too bad. If you
| agree that a structure value is not an object, then an array value
| within that structure value is not an object either. Values don't have
| addresses, storage durations, or other attributes associated with
| objects except type.

Do you agree that (a = b).arr[0] is an lvalue?
Gaby,

No, it is not an lvalue. An lvalue refers to an object. An object is a
named region of storage (with an implied address). (a = b).arr[0] is a
value within a value. Not an object.
 
G

Gabriel Dos Reis

| Gabriel Dos Reis wrote:
| >
| >
| > [...]
| >
| > | > > > struct { int arr[2]; } a, b;
| > | > > >
| > | > > > ( a = b ).arr[0] = 6;
| > | > > > int *p = ( a = b ).arr;
| > | > > > *p = 7;
| > | > >
| > | > > Again, ( a = b ) is a value, not an object. Knowing that a.arr and b.arr
| > | > > are in different structures, which do you assign 6 to? Which do you
| > | > > expect p to point to?
| > | >
| > | > *I* wouldn't expect it to point to either of them, but the standard says
| > | > nothing about it. That's the problem.
| > |
| > | There are many things the Standard does not address. Too bad. If you
| > | agree that a structure value is not an object, then an array value
| > | within that structure value is not an object either. Values don't have
| > | addresses, storage durations, or other attributes associated with
| > | objects except type.
| >
| > Do you agree that (a = b).arr[0] is an lvalue?
| >
| Gaby,
|
| No, it is not an lvalue.

Which part of the standard says that?

[#2] A postfix expression followed by an expression in
square brackets [] is a subscripted designation of an
element of an array object. The definition of the subscript
operator [] is that E1[E2] is identical to (*((E1)+(E2))).
Because of the conversion rules that apply to the binary +
operator, if E1 is an array object (equivalently, a pointer
to the initial element of an array object) and E2 is an
integer, E1[E2] designates the E2-th element of E1 (counting
from zero).

[...]

[#4] The unary * operator denotes indirection. If the
operand points to a function, the result is a function
designator; if it points to an object, the result is an
lvalue designating the object. If the operand has type
``pointer to type'', the result has type ``type''. If an
invalid value has been assigned to the pointer, the behavior
of the unary * operator is undefined.83)


| An lvalue refers to an object.

That was precisely my point: That there is an object and the standard
does nto say what its storage duration is.

| An object is a
| named region of storage (with an implied address). (a = b).arr[0] is a
| value within a value. Not an object.

See above.

-- Gaby
 
G

Gabriel Dos Reis

[...]

| > No, it is not an lvalue. An lvalue refers to an object.
|
| You might want to prevent confusion by saying
| ``an lvalue designates a valid object for storage''

An lvalue is what the Standard says is an lvalue. Now, the issue is
whether there isn't a self contradiction or a hole.

-- Gaby
 
J

j

Joe Wright said:
Gabriel said:
[...]

| > > > struct { int arr[2]; } a, b;
| > > >
| > > > ( a = b ).arr[0] = 6;
| > > > int *p = ( a = b ).arr;
| > > > *p = 7;
| > >
| > > Again, ( a = b ) is a value, not an object. Knowing that a.arr and b.arr
| > > are in different structures, which do you assign 6 to? Which do you
| > > expect p to point to?
| >
| > *I* wouldn't expect it to point to either of them, but the standard says
| > nothing about it. That's the problem.
|
| There are many things the Standard does not address. Too bad. If you
| agree that a structure value is not an object, then an array value
| within that structure value is not an object either. Values don't have
| addresses, storage durations, or other attributes associated with
| objects except type.

Do you agree that (a = b).arr[0] is an lvalue?
Gaby,

No, it is not an lvalue. An lvalue refers to an object.

You might want to prevent confusion by saying
``an lvalue designates a valid object for storage''

Otherwise, by saying ``an lvalue _refers_ to an object''
opens you up to accepting that whatever is on the right-hand of
an assignment operator _refers_ to an object for the value of that
expression.

An object is a
named region of storage (with an implied address). (a = b).arr[0] is a
value within a value. Not an object.
 
W

Wojtek Lerch

j said:
Only under c99. In c90 it doesn't decay at all.

Right; and therefore in C90 fun().arr[0] is illegal, and the problem we're
arguing about doesn't exist.
lawerence jones is the one who pointed this out. Since I don't have a copy
of the c90
standard he would have to point out the relevant sections.

I don't have a copy of C90 either, but have no doubt he knew what he was
talking about.
 
A

Andy Zhang

Avinash said:
#include<stdio.h>
void main()
{
int x[5]={1,2,3,4,5};
printf("\naddr in x:%p",x);
printf("\nnumber in the addr stored in x is:%d",*x);
x=x+1;
printf("\naddr in x after incrementation is:%p",x);
printf("\nnumber in the addr stored in x is:%d",*x);
}

Hay Ambika,
What I understood from your problem is you want to print address of
some element in the array.
First thing, You are trying to increment the base address of array,
which is not allowed in c, See the problem is C compiler do not have
any kind of Array Bounds checking, It can work with array because it
know the base address of the array, and if you try to change the base
address of the array, then C compile will go in vague condition. So
never change the base address
rather than do one thing take another integer pointer and assign it
the base address of the array and then increment that you will get the
answeryou expect.

thanking you.

If you have an array, a pointer to the array can be safely incremented up to
the number of elements in that array:

#include <stdio.h>

int main()
{
int x[5]={1,2,3,4,5};
int *p = x;
p++;
printf("%i\n", *p); /*will print out second element in array, 2*/
return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
474,083
Messages
2,570,591
Members
47,212
Latest member
RobynWiley

Latest Threads

Top