doubt in USING POINTERS

B

Bigdakine

Subject: doubt in USING POINTERS
From: (e-mail address removed) (ambika)
Date: 9/21/03 4:28 AM Hawaiian Standard Time
Message-id: <[email protected]>

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;

You can't increment x, which is a pointer to an array position like that,
hence you get the message unmodifiable L-value. Good thing too. All sorts of
trouble could result. Instead after defining x, add the statement
int ptr2xelem* = (int *) NULL;

And then set
ptr2xelem=&x[0];

And then you can write things like ptr2x++;
If you want to keep track of an index or something like that.
printf("\naddr in x after incrementation is:%p",x);
printf("\nnumber in the addr stored in x is:%d",*x);
}

Stuart
 
B

Barry Schwarz

Subject: doubt in USING POINTERS
From: (e-mail address removed) (ambika)
Date: 9/21/03 4:28 AM Hawaiian Standard Time
Message-id: <[email protected]>

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;

You can't increment x, which is a pointer to an array position like that,
hence you get the message unmodifiable L-value. Good thing too. All sorts of
trouble could result. Instead after defining x, add the statement
int ptr2xelem* = (int *) NULL;

If you are going to assign a real value to the pointer later, the
initialization is only window dressing . However, if you want to use
it, get rid of the ugly and useless cast. And while you are at it,
correct the syntax error.
int *ptr2xelem = NULL;
And then set
ptr2xelem=&x[0];

It would be just as correct to say
ptr2xelem = x;
And then you can write things like ptr2x++;
If you want to keep track of an index or something like that.

%p requires the corresponding argument be cast to void* and you
probably meant ptr2xelem, not x.
printf("\naddr in x after incrementation is:%p",(void*)ptr2xelem);

ptr2xelem again.



<<Remove the del for email>>
 
P

pete

Gabriel said:
| Gabriel Dos Reis wrote:
| >
| >
| > | Irrwahn Grausewitz wrote:
| > | >>| No, arrays are lvalues.
| > | >>Not always.
| > | > For non-experts like me, in what contexts an array is not an lvalue?
| > |
| > | None.
| >
| > Consider
| >
| > struct Point {
| > int coord[2];
| > };
| >
| > extern make_point(int, int);
^

oops, missing "struct Point"

| >
| > The expression
| >
| > make_point(34, 2).coord
| >
| > is a non-lvalue array.
|
| Assuming that make_point returns the appropriate type structure,
| what's nonlvalue about make_point(34, 2).coord ?

6.5.2.3

[#3] A postfix expression followed by the . operator and an
identifier designates a member of a structure or union
object. The value is that of the named member, and is an
lvalue if the first expression is an lvalue. If the first
expression has qualified type, the result has the so-
qualified version of the type of the designated member.

Thank you.
 
M

Mantorok Redgormor

Gabriel Dos Reis said:
| Irrwahn Grausewitz wrote:
| >>| No, arrays are lvalues.
| >>Not always.
| > For non-experts like me, in what contexts an array is not an lvalue?
|
| None.

Consider

struct Point {
int coord[2];
};

extern make_point(int, int);

The expression

make_point(34, 2).coord

How are you allowed to use the '.' operator at the end of this function?
This is like saying:
strcpy(dest, src).coord

That makes no sense.. what am I missing here?
 
G

Gabriel Dos Reis

(e-mail address removed) (Mantorok Redgormor) writes:

| >
| > | Irrwahn Grausewitz wrote:
| > | >>| No, arrays are lvalues.
| > | >>Not always.
| > | > For non-experts like me, in what contexts an array is not an lvalue?
| > |
| > | None.
| >
| > Consider
| >
| > struct Point {
| > int coord[2];
| > };
| >
| > extern make_point(int, int);
| >
| > The expression
| >
| > make_point(34, 2).coord
|
| How are you allowed to use the '.' operator at the end of this function?

The function make_point() is supposed to return "struct Point" -- as
corrected pointed by someone, and rectified in a subsequent message.

-- Gaby
 
M

Mantorok Redgormor

Gabriel Dos Reis said:
(e-mail address removed) (Mantorok Redgormor) writes:

| >
| > | Irrwahn Grausewitz wrote:
| > | >>| No, arrays are lvalues.
| > | >>Not always.
| > | > For non-experts like me, in what contexts an array is not an lvalue?
| > |
| > | None.
| >
| > Consider
| >
| > struct Point {
| > int coord[2];
| > };
| >
| > extern make_point(int, int);
| >
| > The expression
| >
| > make_point(34, 2).coord
|
| How are you allowed to use the '.' operator at the end of this function?

The function make_point() is supposed to return "struct Point" -- as
corrected pointed by someone, and rectified in a subsequent message.

-- Gaby

Yes but why are you using the '.' member operator on a function?

Calling a function and trying to use the member operator '.' on it to
access a member of a struct is illegal.

- nethlek
 
I

Irrwahn Grausewitz

Gabriel Dos Reis said:
(e-mail address removed) (Mantorok Redgormor) writes:

| Gabriel Dos Reis <[email protected]> wrote in message news:<[email protected]>...
| > struct Point {
| > int coord[2];
| > };
| >
| > extern make_point(int, int);
| >
| > The expression
| >
| > make_point(34, 2).coord
|
| How are you allowed to use the '.' operator at the end of this function?

The function make_point() is supposed to return "struct Point" -- as
corrected pointed by someone, and rectified in a subsequent message.

Yes but why are you using the '.' member operator on a function?

Calling a function and trying to use the member operator '.' on it to
access a member of a struct is illegal.
The '.' operator is applied to the _return value_ of the function, which
is a struct in this case.

Regards

Irrwahn
 
G

Gabriel Dos Reis

(e-mail address removed) (Mantorok Redgormor) writes:


[...]

| > The function make_point() is supposed to return "struct Point" -- as
| > corrected pointed by someone, and rectified in a subsequent message.
| >
| > -- Gaby
|
| Yes but why are you using the '.' member operator on a function?

Because the expression make_point(34, 2) is a value of type struct Point.

| Calling a function and trying to use the member operator '.' on it to
| access a member of a struct is illegal.

No.

-- Gaby
 
J

John Bode

Gabriel Dos Reis said:
(e-mail address removed) (Mantorok Redgormor) writes:

| >
| > | Irrwahn Grausewitz wrote:
| > | >>| No, arrays are lvalues.
| > | >>Not always.
| > | > For non-experts like me, in what contexts an array is not an lvalue?
| > |
| > | None.
| >
| > Consider
| >
| > struct Point {
| > int coord[2];
| > };
| >
| > extern make_point(int, int);
| >
| > The expression
| >
| > make_point(34, 2).coord
|
| How are you allowed to use the '.' operator at the end of this function?

The function make_point() is supposed to return "struct Point" -- as
corrected pointed by someone, and rectified in a subsequent message.

-- Gaby

Yes but why are you using the '.' member operator on a function?

Calling a function and trying to use the member operator '.' on it to
access a member of a struct is illegal.

The '.' is applied to the *value returned* by the function, which is
of a struct type. It's perfectly legal (and inspired a particularly
evil IOCCC entry, which had statements like a().b().c().e().f()...).
It's just not an lvalue.
 
M

Mantorok Redgormor

Gabriel Dos Reis said:
(e-mail address removed) (Mantorok Redgormor) writes:


[...]

| > The function make_point() is supposed to return "struct Point" -- as
| > corrected pointed by someone, and rectified in a subsequent message.
| >
| > -- Gaby
|
| Yes but why are you using the '.' member operator on a function?

Because the expression make_point(34, 2) is a value of type struct Point.

| Calling a function and trying to use the member operator '.' on it to
| access a member of a struct is illegal.

No.

-- Gaby

I don't follow. The below is a program demonstrating my lack of
understanding. Could you change it to show what you are doing in a
practical example and how it works?

#include <stdio.h>

struct foo {
int coord[10];
};

static struct foo example(int );

int main(void)
{
/* The below is weird and demonstrates my lack of understanding */
example(10).coord;
/* What do we achieve in the above? how do we access coord?
* I am lost. Help my find my way to understanding */

return 0;
}

struct foo example(int a)
{
/* The below also demonstrates my lack of understanding of what is
* trying to be achieved here. */
static struct foo test;
return test;
}

This is really obfuscated use of a struct member so if you could point
out what the function example() is suppose to return and what is
suppose to happen with coord and how to access "coord" that would be
much appreciated.
 
I

Irrwahn Grausewitz

Gabriel Dos Reis said:
(e-mail address removed) (Mantorok Redgormor) writes:

| Yes but why are you using the '.' member operator on a function?

Because the expression make_point(34, 2) is a value of type struct Point.

| Calling a function and trying to use the member operator '.' on it to
| access a member of a struct is illegal.

No.

I don't follow. The below is a program demonstrating my lack of
understanding. Could you change it to show what you are doing in a
practical example and how it works?

#include <stdio.h>

struct foo {
int coord[10];
};

static struct foo example(int );

int main(void)
{
/* The below is weird and demonstrates my lack of understanding */
example(10).coord;
/* What do we achieve in the above? how do we access coord?
* I am lost. Help my find my way to understanding */

1. The expression example(10) is evaluated, yielding a value
of type struct foo

2. The member coord of this value is accessed via the '.' operator

We access a member A of an object B of type struct C using the
struct member access operator. No magic.
return 0;
}

struct foo example(int a)
{
/* The below also demonstrates my lack of understanding of what is
* trying to be achieved here. */
static struct foo test;
return test;
}

This is really obfuscated use of a struct member so if you could point
out what the function example() is suppose to return and what is
suppose to happen with coord and how to access "coord" that would be
much appreciated.

It's as obfuscated as any other piece of C code. ;-)

example() is a function taking an argument of type int, returning
a value of struct foo.

test is an object of type struct foo with function scope (it is only
accessible in example()) and static storage duration (it gets
initialized on program startup and stays allocated till program
termination).

example() returns a copy of test when called.

Again, no magic.

Regards

Irrwahn
 
J

Jarno A Wuolijoki

struct foo {
int coord[10];
};
static struct foo example(int );

1. The expression example(10) is evaluated, yielding a value
of type struct foo

2. The member coord of this value is accessed via the '.' operator

We access a member A of an object B of type struct C using the
struct member access operator. No magic.

But if I write:

int *p=example(10).coord;

p is indeterminate here right? (since the instance of
struct foo isn't with us anymore)

Is example(10).coord[0] any different then?
 
G

Gabriel Dos Reis

| But if I write:
|
| int *p=example(10).coord;
|
| p is indeterminate here right? (since the instance of
| struct foo isn't with us anymore)

p becomes a dangling pointer, yes.

| Is example(10).coord[0] any different then?

Yes.

int x = example(10).coord[0];

is well defined;
 
B

Barry Margolin

| But if I write:
|
| int *p=example(10).coord;
|
| p is indeterminate here right? (since the instance of
| struct foo isn't with us anymore)

p becomes a dangling pointer, yes.

| Is example(10).coord[0] any different then?

Yes.

int x = example(10).coord[0];

is well defined;

Maybe the following will help.

x = example(10).a;

is for the most part equivalent to:

{ struct foo temp;
temp = example(10);
x = a;
}

The main difference I can think of offhand is that you can use
example(10).a in an expression, but you can't use the equivalent sequence
of statements involving the temp variable so concisely.
 
J

Jarno A Wuolijoki

| Is example(10).coord[0] any different then?

Yes.
int x = example(10).coord[0];
is well defined;

Maybe the following will help.

x = example(10).a;
is for the most part equivalent to:

{ struct foo temp;
temp = example(10);
x = a;
}

But is

x=example(10).coord[0];

equivalent to

{ int *temp;
{ struct foo temp2;
temp2 = example(10);
temp = temp2.coord;
}
x=temp[0];
}

or

{ int *temp;
struct foo temp2;
temp2 = example(10);
temp = temp2.coord;
x=temp[0];
}

?
 
M

Mantorok Redgormor

Gabriel Dos Reis said:
| Irrwahn Grausewitz wrote:
| >>| No, arrays are lvalues.
| >>Not always.
| > For non-experts like me, in what contexts an array is not an lvalue?
|
| None.

Consider

struct Point {
int coord[2];
};

extern make_point(int, int);

The expression

make_point(34, 2).coord

is a non-lvalue array.

-- Gaby

After playing around with this and getting a better understanding I
see how it all works. But, is this array really an array or does coord
just decay into a pointer to the arrays first element? And if so, in
that case the array is not really an rvalue just a pointer to the
array is.

Which is equivalent in saying the array in the following example is an
rvalue:

int arr[10];
int *p;

p = arr; /*
* arr just decays into a pointer to int -- so the array is
not really
* an rvalue but a pointer to int instead, which designates
the
* appropriate object.
*/
 
G

Gabriel Dos Reis

(e-mail address removed) (Mantorok Redgormor) writes:

| After playing around with this and getting a better understanding I
| see how it all works. But, is this array really an array or does coord
| just decay into a pointer to the arrays first element?

It is an array, albeit a non-lvalue. It can decay to pointer in
appropriate context (e.g. function call argument). You can even take
its sizeof and compute its length.

-- Gaby
 
B

Barry Margolin

But is

x=example(10).coord[0];

equivalent to

{ int *temp;
{ struct foo temp2;
temp2 = example(10);
temp = temp2.coord;
}
x=temp[0];
}

or

{ int *temp;
struct foo temp2;
temp2 = example(10);
temp = temp2.coord;
x=temp[0];
}

?

The latter. In the first one, temp is a pointer to an object whose
lifetime has ended when the inner block finishes.

If any temporaries are needed to evaluate an expression, their lifetimes
all must include the entire expression. In some cases it may be possible
to determine that some are no longer needed earlier in the processing, so
an optimizer can eliminate them. But in this case the structure has to
live until the array is dereferenced.
 
M

Mantorok Redgormor

Gabriel Dos Reis said:
(e-mail address removed) (Mantorok Redgormor) writes:

| After playing around with this and getting a better understanding I
| see how it all works. But, is this array really an array or does coord
| just decay into a pointer to the arrays first element?

It is an array, albeit a non-lvalue. It can decay to pointer in
appropriate context (e.g. function call argument). You can even take
its sizeof and compute its length.

-- Gaby

This is great. I have never known this. In this specific context an
array on the right-hand side of an assignment operator does not decay
into a pointer to its first element!

I put together the following example:

#include <stdio.h>
struct foo { int array[10]; };
static struct foo example(int);
int main(void)
{
printf("%u\n", sizeof example(10).array);

return 0;
}

struct foo example(int a)
{
static struct foo woo;
woo.array[0] = a; /* pointless */
return woo;
}


But now, something I found to be bizarre was the fact that sizeof
computed the size of the array. I only say this is bizzare because I
thought sizeof did not evaluate its operand? In this specific case it
would have to evaluate its operand to get the size, right?
Furthermore, it would have to compute this size at run-time and not
compile-time, correct?
 
J

j

Mantorok Redgormor said:
Gabriel Dos Reis <[email protected]> wrote in message
(e-mail address removed) (Mantorok Redgormor) writes:

| After playing around with this and getting a better understanding I
| see how it all works. But, is this array really an array or does coord
| just decay into a pointer to the arrays first element?

It is an array, albeit a non-lvalue. It can decay to pointer in
appropriate context (e.g. function call argument). You can even take
its sizeof and compute its length.

-- Gaby

This is great. I have never known this. In this specific context an
array on the right-hand side of an assignment operator does not decay
into a pointer to its first element!

I put together the following example:

#include <stdio.h>
struct foo { int array[10]; };
static struct foo example(int);
int main(void)
{
printf("%u\n", sizeof example(10).array);

return 0;
}

struct foo example(int a)
{
static struct foo woo;
woo.array[0] = a; /* pointless */
return woo;
}


But now, something I found to be bizarre was the fact that sizeof
computed the size of the array. I only say this is bizzare because I
thought sizeof did not evaluate its operand? In this specific case it
would have to evaluate its operand to get the size, right?
Furthermore, it would have to compute this size at run-time and not
compile-time, correct?

With a later version of gcc(2.96-113 redhat) I get a diagnostic when
attempting to assign to a pointer to int.
int *p;
p = example(10).array;
``invalid use of non-lvalue array''

With gcc 3.2.1 I get ``incompatible types in assignment''

and with lcc-win32 it compiles fine.

Either this is a bug in gcc, or lcc is in violation of the standard.

Is the array member of the struct actually decaying into a pointer to its
first element(int *) or is it actually not decaying?
 

Ask a Question

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

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

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,216
Latest member
topweb3twitterchannels

Latest Threads

Top