473,385 Members | 1,707 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

doubt in USING POINTERS

Hello,
Am not very good with pointers in C,but I have a small doubt about
the way these pointers work..
We all know that in an array say x[5],x is gonna point to the first
element in that array(i.e)it will have the address of the first
element.In the the program below am not able to increment the value
stored in x,which is the address of the first element.Why am I not
able to do that?Afterall 1 is also a hexadecimal number then why
does adding 1 to x show me a error?
I got the message "Lvalue Required" when I complied the program.Even
if I declared x[5] as long int the same error continued.Can
someone please help me solve it out??
Thanks to all those who are gonna help me in this..
--ambika

#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);
}
Nov 13 '05
138 5082
In comp.std.c James Kuyper <ku****@saicmodis.com> wrote:

You're correct. The lifetime of that int object is the same as the
lifetime of the structure object it's a member of: the full-expression
containing the function call.


Not in C; it's only valid until the next sequence point.

-Larry Jones

I've got to start listening to those quiet, nagging doubts. -- Calvin
Nov 13 '05 #101
James Kuyper wrote:
... It's only
rarely possible to squeeze a structure into a register; I don't think
it's a major burden on code generators to effectively prohibit that
option.


However, it is precisely for small structures that one gets the
greatest benefit. The compilers and applications for the Blit
family of programmable bit-map graphics terminals (5620, 630, 730)
took advantage of a similar capability, in particular for
struct point { short x, y; }
for purposes of speed, which was quite important in that context.
Nov 13 '05 #102
la************@eds.com writes:
In comp.std.c Gabriel Dos Reis <gd*@integrable-solutions.net> wrote:

Keith Thompson <ks*@cts.com> writes:
|
| (I'm not quite sure what gcc *should* do with this.)

decay func().arr to a pointer, successfully complete the translation,
and generate a sensible executable.


And a warning that the pointer you stored is useless.


I've just suggested that; see
<http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12446>.

--
Keith Thompson (The_Other_Keith) ks*@cts.com <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Schroedinger does Shakespeare: "To be *and* not to be"
Nov 13 '05 #103
th*@cs.ucr.edu wrote:
In comp.std.c Jeremy Yallop <je****@jdyallop.freeserve.co.uk> wrote:
+ th*@cs.ucr.edu wrote:
+> In comp.std.c Chris Torek <no****@elf.eng.bsdi.com> wrote:
+> [...]
+> + The way I prefer to describe situations involving arrays uses
+> + somewhat different terminology from that in the C standards. In
+> + my notation, we have "objects" and "values", rather than "lvalues"
+> + and "values".
+>
+> Agreed. C89/90 attempted to define an "lvalue" to be an object-valued
+> expression but ran afoul of the fact that to maintain sanity we must
+> accept "*0" as an lvalue.
+
+ I don't see why. "*0" violates a constraint.

The expression "*0" doesn't denote an object.


"*0" is not a valid expression at all. No C implementation is
required to translate a program containing such an expression, because
"0" is not an acceptable operand for unary "*". You may be thinking
of "*(int *)0" or similar.

Jeremy.
Nov 13 '05 #104
In comp.std.c Kevin Bracey <ke**********@tematic.com> wrote:

And why are we only worried about structure returns here? Doesn't C99's new
lvalue definition also allow weird things like

int *x = &abs(1);
*&abs(3) = 2


No.

-Larry Jones

I always send Grandma a thank-you note right away. ...Ever since she
sent me that empty box with the sarcastic note saying she was just
checking to see if the Postal Service was still working. -- Calvin
Nov 13 '05 #105
thp
In comp.std.c Jeremy Yallop <je****@jdyallop.freeserve.co.uk> wrote:
+ th*@cs.ucr.edu wrote:
+> In comp.std.c Jeremy Yallop <je****@jdyallop.freeserve.co.uk> wrote:
+> + th*@cs.ucr.edu wrote:
+> +> In comp.std.c Chris Torek <no****@elf.eng.bsdi.com> wrote:
+> +> [...]
+> +> + The way I prefer to describe situations involving arrays uses
+> +> + somewhat different terminology from that in the C standards. In
+> +> + my notation, we have "objects" and "values", rather than "lvalues"
+> +> + and "values".
+> +>
+> +> Agreed. C89/90 attempted to define an "lvalue" to be an object-valued
+> +> expression but ran afoul of the fact that to maintain sanity we must
+> +> accept "*0" as an lvalue.
+> +
+> + I don't see why. "*0" violates a constraint.
+>
+> The expression "*0" doesn't denote an object.
+
+ "*0" is not a valid expression at all. No C implementation is
+ required to translate a program containing such an expression, because
+ "0" is not an acceptable operand for unary "*". You may be thinking
+ of "*(int *)0" or similar.

Oops! Yes, that's what I meant.

Thanks,
Tom Payne

Nov 13 '05 #106
<la************@eds.com> wrote in message
news:oo************@jones.homeip.net...
In comp.std.c James Kuyper <ku****@saicmodis.com> wrote:

You're correct. The lifetime of that int object is the same as the
lifetime of the structure object it's a member of: the full-expression
containing the function call.


Not in C; it's only valid until the next sequence point.


The standard says that trying to *access* it after the next sequence point
produces undefined behaviour, but that's not exactly the same as saying that
that's when its lifetime ends. In particular, I don't think it's clear that
the pointer to such an object becomes indeterminate at the next sequence
point.

int main(void)
{
int *ptr = func().arr, a;
return &a == ptr; // Undefined?
}
Nov 13 '05 #107
James Kuyper wrote:
CBFalconer wrote:
la************@eds.com wrote:

...
The theory is that the return value has to be stored somewhere
and thus has a conceptual address, even if it's not in the usual
address space, and the resulting pointer has such a short
lifetime that the compiler can get the right answer without too
much work, even if it has to be special-cased.


Since C, unlike Pascal, allows a return value to be ignored, such
needs to be (in practice) easily done. The easiest method is
returning it in a register, and failing to store that register.
Registers do not have an address in the usual memory space. Thus
I see no reason for allowing taking the address of a returned
value, or a component thereof.

If C99 allows this I consider it an unnecessary burden on code
generators.


As I understand the argument, it only applies to the case where
the address being taken is the address of a member of structure.
It's only rarely possible to squeeze a structure into a register;
I don't think it's a major burden on code generators to
effectively prohibit that option.


Consider a machine with a stack and registers too small to hold
the return value (some form of struct). Where is it to place that
value? Local space is not allowed, since it goes out of scope.
It could malloc space and return a pointer, but that involves
special consideration after use by the caller.

The caller can allocate stack space at some agreed upon offset,
and the function can store the results there. This allows the
caller to purge it together with any passed parameters, for
"caller cleans up" protocols.

Having done this, that space goes out of scope slightly later that
the rest of the function variables, but it still goes. To save
the value it must be copied somewhere. No address of any portion
of the return can be taken, because that storage may shortly (next
instruction or so) be released.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #108
thp
In comp.std.c Douglas A. Gwyn <DA****@null.net> wrote:
+ th*@cs.ucr.edu wrote:
+> Agreed. C89/90 attempted to define an "lvalue" to be an object-valued
+> expression but ran afoul of the fact that to maintain sanity we must
+> accept "*0" as an lvalue. We might slip out of that embarrassment by
+> positing a "null object" that *0 designates, but what's its type?
+> Obviously, the matter gets even more difficult when there are
+> reference types.
+
+ That's completely wacky. "*0" is not allowed in strictly conforming

Oops, make that "*(int*)0".

+ programs, does not occur in any program I know of, and is perforce
+ irrelevant to the C standard.

Tom Payne
Nov 13 '05 #109
Gabriel Dos Reis <gd*@integrable-solutions.net> wrote in message news:<m3************@uniton.integrable-solutions.net>...
James Kuyper <ku****@saicmodis.com> writes:

| Keith Thompson wrote:
| ...
| > I still wonder about the semantics of this. I've just tried another
| > test program that assigns a value to *ptr and then prints it out.
| > This doesn't, of course, imply that doing so is valid; it could still
| > be undefined behavior.
| >
| > The question is, what is the lifetime of the int object that ptr
| > points to? It's part of the value returned by a function, so I
| > normally wouldn't expect it to outlive the expression containing the
| > call, but being able to grab a pointer to it makes it all very
| > confusing.
|
| You're correct. The lifetime of that int object is the same as the
| lifetime of the structure object it's a member of: the full-expression
| containing the function call. It outlasts the function call itself, and
| can therefore be used in parts of the same full-expression that are
| guaranteed to be evaluated after the function call, but it cannot be
| used in the next statement after the one containing the function call.

Do you have formal reference(s) for that claim?


Yes, I do: section 12.2p3. Unfortunately, it's from the C++ standard.
:-( Sorry!

The correct answer for C99 is that the returned structure remains
useable only until the next sequence point (6.5.2.2p5).
Nov 13 '05 #110
"Wojtek Lerch" <Wo******@yahoo.ca> wrote in message news:<gB******************@news02.bloor.is.net.cab le.rogers.com>...
....
The standard says that trying to *access* it after the next sequence point
produces undefined behaviour, but that's not exactly the same as saying that
that's when its lifetime ends. In particular, I don't think it's clear that
the pointer to such an object becomes indeterminate at the next sequence
point.


The purpose of the concept of "lifetime" is to describe the period of
time during which the object can be accessed. I don't think you can
make that distinction.
Nov 13 '05 #111
ku****@wizard.net (James Kuyper) writes:

| The correct answer for C99 is that the returned structure remains
| useable only until the next sequence point (6.5.2.2p5).

yep. Not very useful, IMO :-(

-- Gaby
Nov 13 '05 #112
ku****@wizard.net (James Kuyper) wrote in message news:<8b**************************@posting.google. com>...
"Wojtek Lerch" <Wo******@yahoo.ca> wrote in message news:<gB******************@news02.bloor.is.net.cab le.rogers.com>...
...
The standard says that trying to *access* it after the next sequence point
produces undefined behaviour, but that's not exactly the same as saying that
that's when its lifetime ends. In particular, I don't think it's clear that
the pointer to such an object becomes indeterminate at the next sequence
point.


The purpose of the concept of "lifetime" is to describe the period of
time during which the object can be accessed. I don't think you can
make that distinction.


No, the purpose of the concept of "lifetime" is to describe the period
of time *outside of which* you can't access the object and you can't
even have a pointer to the object. *During* that period, accessing
the object may or may not produce undefined behaviour, depending on
numerous details of how you try to access it, what its contents are,
whether restrict pointers to it exist, and so on. It's an important
distinction: just because trying to access an object produces
undefined behaviour for some reason, it doesn't mean that the object's
lifetime has ended and any pointer that used to point to it is not a
valid pointer any more. And 6.5.2.2p5 doesn't talk about the lifetime
-- it's just one of the many places that talk about undefined
behaviour.

In short, when an object's lifetime ends is not determined by whether
accessing the object produces undefined behaviour or not. It's
determined by the object's storage duration (6.2.4p1). Trouble is,
the C standard seems to have forgotten to define a type of storage
duration suitable for those temporary objects returned by a function.
If you assume that it must be one of the three defined storage
durations, the pointer should stay valid until at least the end of the
block, right?...
Nov 13 '05 #113
th*@cs.ucr.edu writes:
In comp.std.c Douglas A. Gwyn <DA****@null.net> wrote:
+ th*@cs.ucr.edu wrote:
+> Agreed. C89/90 attempted to define an "lvalue" to be an object-valued
+> expression but ran afoul of the fact that to maintain sanity we must
+> accept "*0" as an lvalue. We might slip out of that embarrassment by
+> positing a "null object" that *0 designates, but what's its type?
+> Obviously, the matter gets even more difficult when there are
+> reference types.
+
+ That's completely wacky. "*0" is not allowed in strictly conforming

Oops, make that "*(int*)0".


The above expression invokes UB, unless it is immediately the
operand of &.

-Micah
Nov 13 '05 #114
Wojtek Lerch <Wo******@yahoo.ca> wrote in message
news:ca*************************@posting.google.co m...
ku****@wizard.net (James Kuyper) wrote in message

news:<8b**************************@posting.google. com>...
"Wojtek Lerch" <Wo******@yahoo.ca> wrote in message news:<gB******************@news02.bloor.is.net.cab le.rogers.com>... ...
The standard says that trying to *access* it after the next sequence point produces undefined behaviour, but that's not exactly the same as saying that that's when its lifetime ends. In particular, I don't think it's clear that the pointer to such an object becomes indeterminate at the next sequence point.


The purpose of the concept of "lifetime" is to describe the period of time during which the object can be accessed. I don't think you can
make that distinction.


No, the purpose of the concept of "lifetime" is to describe the period
of time *outside of which* you can't access the object and you can't
even have a pointer to the object. *During* that period, accessing
the object may or may not produce undefined behaviour, depending on
numerous details of how you try to access it, what its contents are,
whether restrict pointers to it exist, and so on. It's an important
distinction: just because trying to access an object produces
undefined behaviour for some reason, it doesn't mean that the object's
lifetime has ended and any pointer that used to point to it is not a
valid pointer any more. And 6.5.2.2p5 doesn't talk about the lifetime
-- it's just one of the many places that talk about undefined
behaviour.

In short, when an object's lifetime ends is not determined by whether
accessing the object produces undefined behaviour or not. It's
determined by the object's storage duration (6.2.4p1). Trouble is,
the C standard seems to have forgotten to define a type of storage
duration suitable for those temporary objects returned by a function.
If you assume that it must be one of the three defined storage
durations, the pointer should stay valid until at least the end of the
block, right?...


I think not. Functions return values, not objects. The concept of an
address of a value or of a member of a value is foreign to me. Assign
the value returned by the function to a suitable object and operate on
the object.

Nov 13 '05 #115
Micah Cowan wrote:
th*@cs.ucr.edu writes:

....
Oops, make that "*(int*)0".


The above expression invokes UB, unless it is immediately the
operand of &.


Or sizeof.

Jirka

Nov 13 '05 #116
In comp.std.c CBFalconer <cb********@yahoo.com> wrote:

Having done this, that space goes out of scope slightly later that
the rest of the function variables, but it still goes. To save
the value it must be copied somewhere. No address of any portion
of the return can be taken, because that storage may shortly (next
instruction or so) be released.


"Slightly later" must be at least the next sequence point, since you
need to be able to assign the entire struct or access members. That
just happens to be exactly the same as the lifetime of the pointer you
get from a contained array. The only reason the pointer is allowed to
exist at all is so that it can be immediately dereferenced; there is no
point in storing it for later use since what it points to will, as you
say, no longer exist. It's just plain silly to allow f().x but not
allow f().a[0].

-Larry Jones

I always send Grandma a thank-you note right away. ...Ever since she
sent me that empty box with the sarcastic note saying she was just
checking to see if the Postal Service was still working. -- Calvin
Nov 13 '05 #117
"Joe Wright" <jo********@comcast.net> wrote in message
news:i3********************@comcast.com...
Wojtek Lerch <Wo******@yahoo.ca> wrote in message
In short, when an object's lifetime ends is not determined by whether
accessing the object produces undefined behaviour or not. It's
determined by the object's storage duration (6.2.4p1). Trouble is,
the C standard seems to have forgotten to define a type of storage
duration suitable for those temporary objects returned by a function.
If you assume that it must be one of the three defined storage
durations, the pointer should stay valid until at least the end of the
block, right?...


I think not. Functions return values, not objects. The concept of an
address of a value or of a member of a value is foreign to me. Assign
the value returned by the function to a suitable object and operate on
the object.


I see nothing wrong about a member of a value, provided that the value is a
struct or a union. The address of a value sounds at best suspicious to me,
too; but that's how the C standard is written.

Consider:

struct foo { int x, arr[2]; } fun( void );

int i = fun().x;
int j = fun().arr[0];

The expression "fun()" produces a value (not an lvalue) of type "struct foo"
(6.5.2.2p5).

The expression "fun().x" produces a value (not an lvalue) of type int
(6.5.2.3p3).

The expression "fun().arr" produces a value (not an lvalue) of type "int[2]"
(6.5.2.3p3).

That value is then converted to the pointer to the initial element of the
array (6.3.2.1p3). This is the funny part: the array is not an lvalue, but
for this conversion to happen, its elements must be objects that you can
take the address of.

Dereferencing that pointer produces an lvalue (even though the array wasn't
an lvalue). 6.4.2.2p5 specifically forbids us to modify that lvalue, but
converting it to a value is fine.

Nov 13 '05 #118
thp
In comp.std.c Micah Cowan <mi***@cowan.name> wrote:
+ th*@cs.ucr.edu writes:
+
+> In comp.std.c Douglas A. Gwyn <DA****@null.net> wrote:
+> + th*@cs.ucr.edu wrote:
+> +> Agreed. C89/90 attempted to define an "lvalue" to be an object-valued
+> +> expression but ran afoul of the fact that to maintain sanity we must
+> +> accept "*0" as an lvalue. We might slip out of that embarrassment by
+> +> positing a "null object" that *0 designates, but what's its type?
+> +> Obviously, the matter gets even more difficult when there are
+> +> reference types.
+> +
+> + That's completely wacky. "*0" is not allowed in strictly conforming
+>
+> Oops, make that "*(int*)0".
+
+ The above expression invokes UB, unless it is immediately the
+ operand of &.

Right, but not necessarily so at compile time since it can occur in
a context that is never executed:

if ( 0 ) *(int*)0;

Obviously the frivolity of that construct is obvious at compile time,
but one can construct a function f() such that determing whether f()
is 0 is equivalent to the halting problem. Then the frivolity of

if ( f() ) *(int*)0;

is not statically determinable.

Tom Payne
Nov 13 '05 #119
la************@eds.com wrote:
In comp.std.c CBFalconer <cb********@yahoo.com> wrote:

Having done this, that space goes out of scope slightly later that
the rest of the function variables, but it still goes. To save
the value it must be copied somewhere. No address of any portion
of the return can be taken, because that storage may shortly (next
instruction or so) be released.


"Slightly later" must be at least the next sequence point, since you
need to be able to assign the entire struct or access members. That
just happens to be exactly the same as the lifetime of the pointer you
get from a contained array. The only reason the pointer is allowed to
exist at all is so that it can be immediately dereferenced; there is no
point in storing it for later use since what it points to will, as you
say, no longer exist. It's just plain silly to allow f().x but not
allow f().a[0].


But this is allowed IMO. It is selecting a component value, not
taking any address. The operation is part of the expression
containing the function call, so there is no sequence point before
it is used. This is allied with the fact that an array, as a
component of a structure, is returned by value as an array, not as
any form of pointer.

For the implementor, a must be characterized by an offset from the
start of the containing structure. Indexing that array is just a
matter of adding some multiple of the array element size to that
offset. The compiler knows these values. If the whole schmeer
can be in registers, the implementation must act appropriately.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #120
In comp.std.c CBFalconer <cb********@yahoo.com> wrote:

But this is allowed IMO. It is selecting a component value, not
taking any address. The operation is part of the expression
containing the function call, so there is no sequence point before
it is used. This is allied with the fact that an array, as a
component of a structure, is returned by value as an array, not as
any form of pointer.
But for subscripting to work, the array must be converted into a pointer
to its first element. So it *is* taking an address, implicitly.
For the implementor, a must be characterized by an offset from the
start of the containing structure. Indexing that array is just a
matter of adding some multiple of the array element size to that
offset. The compiler knows these values. If the whole schmeer
can be in registers, the implementation must act appropriately.


Exactly. And since the lifetime of the "object" pointed to is so short,
it's no burden on the compiler to do the right thing. If a user is so
foolish as to try to store that pointer, the compiler is at liberty to
simply make up a value, since it can't possibly be used without invoking
undefined behavior.

-Larry Jones

Girls are so weird. -- Calvin
Nov 13 '05 #121
Wo******@yahoo.ca (Wojtek Lerch) wrote in message news:<ca*************************@posting.google.c om>...
....
In short, when an object's lifetime ends is not determined by whether
accessing the object produces undefined behaviour or not. It's
determined by the object's storage duration (6.2.4p1). Trouble is,
the C standard seems to have forgotten to define a type of storage
duration suitable for those temporary objects returned by a function.
I agree; storage duration was the first place I looked, and I was
rather annoyed to not find it covered. The C++ standard defines the
lifetime of what it calls "temporary objects"; the next C standard
could be improved by borrowing that concept, and perhaps a lot of the
relevant wording, as well.
If you assume that it must be one of the three defined storage
durations, the pointer should stay valid until at least the end of the
block, right?...


Each of the three defined storage durations has a description of the
circumstances under which it applies; none of them cover this case.
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.
Nov 13 '05 #122
"James Kuyper" <ku****@wizard.net> wrote in message
news:8b**************************@posting.google.c om...
Wo******@yahoo.ca (Wojtek Lerch) wrote in message news:<ca*************************@posting.google.c om>... ...
Each of the three defined storage durations has a description of the
circumstances under which it applies; none of them cover this case.
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.
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;

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?...

Nov 13 '05 #123
#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.
Nov 13 '05 #124
Wojtek Lerch wrote:

"James Kuyper" <ku****@wizard.net> wrote in message
news:8b**************************@posting.google.c om...
Wo******@yahoo.ca (Wojtek Lerch) wrote in message news:<ca*************************@posting.google.c om>...
...
Each of the three defined storage durations has a description of the
circumstances under which it applies; none of them cover this case.


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?...


--
Joe Wright http://www.jw-wright.com
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 13 '05 #125
"Wojtek Lerch" <Wo******@yahoo.ca> wrote in message news:<Um****************@news04.bloor.is.net.cable .rogers.com>...
"James Kuyper" <ku****@wizard.net> wrote in message
news:8b**************************@posting.google.c om...

....
Each of the three defined storage durations has a description of the
circumstances under which it applies; none of them cover this case.


Still, 6.2.4p1 says that every object has a storage duration and that only


A return value isn't an object.
Nov 13 '05 #126
"Joe Wright" <jo********@earthlink.net> wrote in message
news:3F***********@earthlink.net...
Wojtek Lerch wrote:
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.


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.

Nov 13 '05 #127
"James Kuyper" <ku****@wizard.net> wrote in message
news:8b**************************@posting.google.c om...
"Wojtek Lerch" <Wo******@yahoo.ca> wrote in message news:<Um****************@news04.bloor.is.net.cable .rogers.com>...
"James Kuyper" <ku****@wizard.net> wrote in message
news:8b**************************@posting.google.c om...

...
Each of the three defined storage durations has a description of the
circumstances under which it applies; none of them cover this case.


Still, 6.2.4p1 says that every object has a storage duration and that

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?
Nov 13 '05 #128
In comp.std.c Wojtek Lerch <Wo******@yahoo.ca> wrote:

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
Nov 13 '05 #129
j

"Wojtek Lerch" <Wo******@yahoo.ca> wrote in message
news:YG*****************@news04.bloor.is.net.cable .rogers.com...
"Joe Wright" <jo********@earthlink.net> wrote in message
news:3F***********@earthlink.net...
Wojtek Lerch wrote:
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.


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.

Nov 13 '05 #130
Wojtek Lerch wrote:

"Joe Wright" <jo********@earthlink.net> wrote in message
news:3F***********@earthlink.net...
Wojtek Lerch wrote:
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.


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.
--
Joe Wright http://www.jw-wright.com
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 13 '05 #131
Joe Wright <jo********@earthlink.net> writes:
[...]

| > > > 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
Nov 13 '05 #132
Gabriel Dos Reis wrote:

Joe Wright <jo********@earthlink.net> writes:

[...]

| > > > 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.
--
Joe Wright http://www.jw-wright.com
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 13 '05 #133
j

"Joe Wright" <jo********@earthlink.net> wrote in message
news:3F***********@earthlink.net...
Gabriel Dos Reis wrote:

Joe Wright <jo********@earthlink.net> writes:

[...]

| > > > 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.
--
Joe Wright http://www.jw-wright.com
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---

Nov 13 '05 #134
Joe Wright <jo********@earthlink.net> writes:

| Gabriel Dos Reis wrote:
| >
| > Joe Wright <jo********@earthlink.net> writes:
| >
| > [...]
| >
| > | > > > 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
Nov 13 '05 #135
"j" <ja*******@bellsouth.net> writes:
[...]

| > 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
Nov 13 '05 #136
<la************@eds.com> wrote in message
news:ao************@jones.homeip.net...
In comp.std.c Wojtek Lerch <Wo******@yahoo.ca> wrote:
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.


Right. Thanks. So it's the same problem, not worse.
Nov 13 '05 #137
"j" <ja*******@bellsouth.net> wrote in message
news:s7*****************@bignews3.bellsouth.net...

"Wojtek Lerch" <Wo******@yahoo.ca> wrote in message
news:YG*****************@news04.bloor.is.net.cable .rogers.com...
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.


Right; and therefore in C90 fun().arr[0] is illegal, and the problem we're
arguing about doesn't exist.
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.


I don't have a copy of C90 either, but have no doubt he knew what he was
talking about.
Nov 13 '05 #138
Avinash wrote:
#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;
}
--
Andy Zhang

Remove "removethis" to reply by email
Nov 13 '05 #139

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

22
by: srivatsan_b | last post by:
Hi, Can somebody explain whether an explicit typecast is mandatory while calling memset function for a structure? like in the following code snapshot..... struct some_structure x;...
28
by: dutche | last post by:
Hi, there is some kind of difference in these two statements? float num = 154.87; printf("There is : $0.0f",num); and float num = 154.87;
10
by: Pedro Pinto | last post by:
Hi there! I'm creating a function that copies some information to a buffer and enters a delimiter string "//" between results. My issue here is when i print the buffer it appears this weird...
6
by: reji_thomas | last post by:
Hi, I have a doubt in the following code: struct xyz { int x; long l; float f; };
5
by: subramanian | last post by:
Consdier the following program: #include <stdio.h> struct typeRecord { int id; char str; } records = { {0, "zero"}, {1, "one"},
4
by: Deep | last post by:
I'm in doubt about what is smart pointer. so, please give me simple description about smart pointer and an example of that. I'm just novice in c++. regards, John.
26
by: Vashna | last post by:
Hi Group, I have a doubt about register variables. I know that if we have a variable used very frequently in a function, then provided we never apply the & function to it, we can define it as...
1
by: sridhard2406 | last post by:
Hi All, I have a doubt on undrestanding Dangling pointers.Below I mentioned sample code. please let me know, my view on Dangling pointers is correct or not? main( ) ...
5
by: nembo kid | last post by:
In the following function, s shouldn't be a pointer costant (array's name)? So why it is legal its increment? Thanks in advance. /* Code starts here */ void chartobyte (char *s) { while...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.