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
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. 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" 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.
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
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
<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?
}
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!
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
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).
"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. 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 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?... 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
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.
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
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
"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.
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 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!
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 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.
"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?...
#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.
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 ---
"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.
"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.
"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?
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
"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.
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 ---
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
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 ---
"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 ---
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
"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
<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.
"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.
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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;...
|
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;
|
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...
|
by: reji_thomas |
last post by:
Hi,
I have a doubt in the following code:
struct xyz
{
int x;
long l;
float f;
};
|
by: subramanian |
last post by:
Consdier the following program:
#include <stdio.h>
struct typeRecord {
int id;
char str;
} records = {
{0, "zero"},
{1, "one"},
|
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.
|
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...
|
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( )
...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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,...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
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...
|
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
|
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...
| |