Pointer assigning.

S

srikar2097

Hi guys/gals,
I have written this snippet of code

int *ptr2=NULL, b[10];
*ptr2 = &b[0];

After (this I do something with ptr2) I compile and get a "Bus
Error".

But if I do it this way I am able to carry on. No Error -
int b[10];
int *ptr2 = &b[0];

What is the difference between the 2 approaches?

Thanks,
Srikar
 
I

Ian Collins

srikar2097 said:
Hi guys/gals,
I have written this snippet of code

int *ptr2=NULL, b[10];
*ptr2 = &b[0];
Here you are attempting to assign an int* to an int (*ptr2). Didn't your
compiler warn you?

If not, either find the options that will or get a better one.
 
S

srikar2097

srikar2097 said:
Hi guys/gals,
I have written this snippet of code
int *ptr2=NULL, b[10];
*ptr2 = &b[0];

Here you are attempting to assign an int* to an int (*ptr2). Didn't your
compiler warn you?

If not, either find the options that will or get a better one.

Thanks Ian for the prompt reply. I have got the warning, but I did not
totally undertand the meaning
of that typecast. It says "warning: assignment makes integer from
pointer without a cast"

I mean I have taken an integer pointer2 and assigned it the base
address of an integer. What's wrong here?

Could you please elaborate "Pointer Typecasting" in this case (and in
general cases). Thanks again...
 
S

srikar2097

srikar2097 said:
Hi guys/gals,
I have written this snippet of code
int *ptr2=NULL, b[10];

This defines a pointer to int, ptr2, and gives it the value NULL - i.e. it
doesn't point at any object.
*ptr2 = &b[0];

This assigns a value (i.e. the address of b's first element) to the object
pointed to by ptr2. But ptr2 doesn't point at any object.

It should be:

ptr2 = &b[0];

Or, equivalently:

ptr2 = b;

Or, if you prefer:

int b[10];
int *ptr2 = b;

Or even:

int b[10], *ptr2 = b;

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999


I think I get what you are trying to explain. Just one more doubt
though...

When we say *ptr2 = &b[0]; -------->1
richard said:
This assigns a value (i.e. the address of b's first
element) to the object pointed to by ptr2. But ptr2 doesn't point at
any object.

I agree to this explanation by richard.

Now when we write int *ptr2 = b[0]; --------->2
How is this (i.e. 2) not same as (1).

Thanks,
Srikar
 
C

CBFalconer

srikar2097 said:
Hi guys/gals,
I have written this snippet of code

int *ptr2=NULL, b[10];
*ptr2 = &b[0];

After (this I do something with ptr2) I compile and get a "Bus
Error".

But if I do it this way I am able to carry on. No Error -
int b[10];
int *ptr2 = &b[0];

This initializes ptr2. Your first code initializes *ptr2.
 
B

Ben Bacarisse

srikar2097 said:
srikar2097 said:
Hi guys/gals,
I have written this snippet of code
int *ptr2=NULL, b[10];
*ptr2 = &b[0];

Here you are attempting to assign an int* to an int (*ptr2). Didn't your
compiler warn you?

If not, either find the options that will or get a better one.

Best not to quote sigs.
Thanks Ian for the prompt reply. I have got the warning, but I did not
totally undertand the meaning
of that typecast. It says "warning: assignment makes integer from
pointer without a cast"

Note that the message says "cast". Typecasting happens to actors! A
cast is used to change the type of an expression so it often gets the
wrong name but you should stick with calling it a cast.
I mean I have taken an integer pointer2 and assigned it the base
address of an integer. What's wrong here?

No. *ptr2 is an integer object to which you are trying to assign a
pointer -- specifically &b[0]. If a variable is defined like this

some_type_it_does_not_matter_what *variable;

then the expression *variable denotes the thing that 'variable' points
to -- it denotes an object of type some_type_it_does_not_matter_what.
Could you please elaborate "Pointer Typecasting" in this case (and in
general cases). Thanks again...

"Pointer casting". It is simply the conversion of a pointer from one
type to another using a cast expression. It is often the wrong way to
do things[1] and is rarely the right thing to do at all. The most common
correct uses are when you are building generic data structures using
void *. When you need to get the real data back you can do that with
a cast. (You don't have to use a cast, but it can shorten the code.)

[1] Lots of bad code uses it when moving data about thereby
introducing byte-order portability bug that need not be there at all.
 
B

Barry Schwarz

srikar2097 said:
Hi guys/gals,
I have written this snippet of code
int *ptr2=NULL, b[10];
*ptr2 = &b[0];

Here you are attempting to assign an int* to an int (*ptr2). Didn't your
compiler warn you?

If not, either find the options that will or get a better one.

Thanks Ian for the prompt reply. I have got the warning, but I did not
totally undertand the meaning
of that typecast. It says "warning: assignment makes integer from
pointer without a cast"

I mean I have taken an integer pointer2 and assigned it the base
address of an integer. What's wrong here?

That may have been your intent but it is not what you wrote. If you
want to assign the address of b[0] to ptr2, your code should read
ptr2 = &b[0];

Look at your code. The right side is a the address of b[0]. It has
type int*. You left side is the int that ptr2 supposedly points to.
(The fact that ptr2 actually contains NULL and therefore doesn't point
anywhere is a run time issue, not a compile time one.) So the
diagnostic is telling you that you cannot assign a value of type int*
to an object of type int.

The wording of the message is technically correct (you could coerce
the value to type int by using a cast) but also misleading. You
almost never want to assign a pointer to an int. The results are
implementation specific and not very portable.

The issue arises from the multiple meanings of the * in the
declaration and the assignment statement. In the declaration, it
means that ptr2 points to an int. In the assignment statement, it
means the the value of ptr2 should be dereferenced to yield the object
pointed to. When you want to deal with the pointer itself as opposed
to the object pointed to, you use the pointer name without the *.
Could you please elaborate "Pointer Typecasting" in this case (and in
general cases). Thanks again...

There is no such thing as typecasting. A cast is an operator in C,
just like + or & or sizeof. The effect of this particular operator is
to convert the value of its operand to the type specified. Most of
the casts you see in public code are either incorrect of superfluous.
People see the same diagnostic you did and think that the compiler is
suggesting a cast as a way to correct the problem. There are very few
times when a cast is necessary. Probably the most common is when
using the %p format in printf. The corresponding argument must be of
type void*. If the pointer you want to print is any other type then
you must cast it.
 
S

srikar2097

srikar2097 said:

<snip>


I think I get what you are trying to explain. Just one more doubt
though...
When we say *ptr2 = &b[0]; -------->1
richard said:
 This assigns a value (i.e. the address of b's first
element) to the object pointed to by ptr2. But ptr2 doesn't point at
any object.
I agree to this explanation by richard.
Now when we write int *ptr2 = b[0]; --------->2

You mean &b[0], but yes.
How is this (i.e. 2) not same as (1).

Let's make the cases clear:

Case 1:
int b[10];
int *ptr2 = NULL;
*ptr2 = &b[0]; /* bug */

Case 2:
int b[10];
int *ptr2 = b; /* no bug */

Now I want to teach you a new language. This new language is exactly like C
in all respects save one - the $ operator is added. It means "contents
of", as in "$x = y;" means "x is a pointer to an object, and we give that
object the new value y". This means that we can keep * to mean purely "I
am now declaring a pointer".

Let's rewrite those cases in our new language:

Case 1:
int b[10];
int *ptr2 = NULL;
$ptr2 = &b[0]; /* bug */

Case 2:
int b[10];
int *ptr2 = b; /* no bug */

I hope that, using our new language with the $ deref operator, it becomes
clear that the assignment on line 3 of Case 1 is wrong. Since ptr2 doesn't
point to any object, we can't dereference it (and in fact we don't really
want to - we were mistaken in adding a dereference operator).

Case 2 shows more clearly that we don't have or want a dereference operator
here. All we want is to assign a pointer value to ptr2. In short, we want
the pointer to point at something.

Case 3 (below) is equivalent:

Case 3:
int b[10];
int *ptr2;
ptr2 = b; /* note - NO dereference */

In our new language, the * - in all three cases - merely means "I am
declaring a pointer object".

In C, however, the * does two jobs (well, actually more than two, but never
mind that for now). It doesn't just mean "I am declaring a pointer
object". It is also used for "I am dereferencing a pointer object". Since
you can't declare and dereference the same pointer at the same time, this
doesn't cause syntactical problems. But it does cause problems of
understanding.

It may (or may not) help to think of "int *p" as meaning "provided p points
somewhere, *p is an int".

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999

Excellent reply Richard!! I am loving it.... Thanks a bunch. You
helped clear lots (and more)...

In your reply you have mentioned something like this -
richard said:
In C, however, the * does two jobs (well, actually
more than two, but never mind that for now)....

I want to know what else could * mean in your sentence. It would
dearly help me to learn more..

Srikar
 
S

s0suk3

In your reply you have mentioned something like this -
richard said:
In C, however, the * does two jobs (well, actually
more than two, but never mind that for now)....

I want to know what else could * mean in your sentence. It would
dearly help me to learn more..

(1) When it appears in front of a declarator in a declaration, it
specifies that the variable being declared is a pointer (unless the
declarator is followed by [] or ())
(2) When used as a unary operator in an expression, it represents
the indirection operator
(3) When used as a binary operator in an expression, it represents
the multiplication operator

Sebastian
 
B

Ben Bacarisse

In your reply you have mentioned something like this -
richard said:
In C, however, the * does two jobs (well, actually
more than two, but never mind that for now)....

I want to know what else could * mean in your sentence. It would
dearly help me to learn more..

(1) When it appears in front of a declarator in a declaration, it
specifies that the variable being declared is a pointer (unless the
declarator is followed by [] or ())
(2) When used as a unary operator in an expression, it represents
the indirection operator
(3) When used as a binary operator in an expression, it represents
the multiplication operator

(4) When used as the size of an array parameter in a function
prototype it indicates that the parameter is a variable length array
whose dimension will be one of the other parameters. Parameters need
not be named in prototypes so there has to be some way to indicate a
VLA without specifying a name.
 
B

Ben Bacarisse

Richard Heathfield said:
Ben Bacarisse said:
In your reply you have mentioned something like this -
richard said:
In C, however, the * does two jobs (well, actually
more than two, but never mind that for now)....

I want to know what else could * mean in your sentence. It would
dearly help me to learn more..

(1) When it appears in front of a declarator in a declaration, it
specifies that the variable being declared is a pointer (unless the
declarator is followed by [] or ())
(2) When used as a unary operator in an expression, it represents
the indirection operator
(3) When used as a binary operator in an expression, it represents
the multiplication operator

(4) When used as the size of an array parameter in a function
prototype it indicates that the parameter is a variable length array
whose dimension will be one of the other parameters. Parameters need
not be named in prototypes so there has to be some way to indicate a
VLA without specifying a name.

(5) When it follows a / and is not currently in a comment, the digraph
starts a comment. When it precedes a / and *is* currently in a comment,
the digraph ends the comment.

(6) (kinda sorta) It also has a meaning in *printf and *scanf format
strings, but that's sort of cheating because it's within a string
literal.

More kinda sorta would be (5b) inside '' and "" where it represents
the * character in the execution character set. If you include /* as
a meaning of * then you have to include '*' (and possibly "*" and all
string literals that include *). My choice, however, would be not to
include any of these compound uses.
 
S

srikar2097

Richard Heathfield said:
Ben Bacarisse said:
(e-mail address removed) writes:
In your reply you have mentioned something like this -
richard said:
In C, however, the * does two jobs (well, actually
more than two, but never mind that for now)....
I want to know what else could * mean in your sentence. It would
dearly help me to learn more..
  (1) When it appears in front of a declarator in a declaration, it
specifies that the variable being declared is a pointer (unless the
declarator is followed by [] or ())
  (2) When used as a unary operator in an expression, it represents
the indirection operator
  (3) When used as a binary operator in an expression, it represents
the multiplication operator
(4) When used as the size of an array parameter in a function
prototype it indicates that the parameter is a variable length array
whose dimension will be one of the other parameters.  Parameters need
not be named in prototypes so there has to be some way to indicate a
VLA without specifying a name.
(5) When it follows a / and is not currently in a comment, the digraph
starts a comment. When it precedes a / and *is* currently in a comment,
the digraph ends the comment.
(6) (kinda sorta) It also has a meaning in *printf and *scanf format
strings, but that's sort of cheating because it's within a string
literal.

More kinda sorta would be (5b) inside '' and "" where it represents
the * character in the execution character set.  If you include /* as
a meaning of * then you have to include '*' (and possibly "*" and all
string literals that include *).  My choice, however, would be not to
include any of these compound uses.

Great Guys! Thanks a lot to Ben, Richard, Barry and others who have so
patiently helped me out.
Here's hoping to learn much more from you all...

Srikar
 
G

gw7rib

Hi guys/gals,
I have written this snippet of code

int *ptr2=NULL, b[10];
*ptr2 = &b[0];

After (this I do something with ptr2) I compile and get a "Bus
Error".

But if I do it this way I am able to carry on. No Error -
int b[10];
int *ptr2 = &b[0];

What is the difference between the 2 approaches?

Thanks,
Srikar

Hi Srikar

There's one other subtlety about what is happening that no-one seems
to have pointed out to you yet (though Richard mentioned it in his
reply to CBFalconer). That is, that the '=' is also doing two
different things in your code above.

In the following line:

int *ptr2 = &b[0];

the = tells the computer what value ptr2 starts off with. This is
called an initialisation.

But in the following line:

ptr2 = &b[0];

the = sets a new value for ptr2. This is called an assignment.

There is not a lot of difference between the two, which is probably
why they have the same symbol, but it is important to be aware of the
difference, particularly if you are going to write in C++. One example
of the difference is that

const int a = 3;

works, giving a a value to 3, which it will stay at, whereas

const int a;
a = 3;

will not work - you can't assign to a, you need to set its value right
at the very beginning.

Hope this helps.
Paul.
 
B

Barry Schwarz

Hi guys/gals,
I have written this snippet of code

int *ptr2=NULL, b[10];
*ptr2 = &b[0];

After (this I do something with ptr2) I compile and get a "Bus
Error".

But if I do it this way I am able to carry on. No Error -
int b[10];
int *ptr2 = &b[0];

What is the difference between the 2 approaches?

Thanks,
Srikar

Hi Srikar

There's one other subtlety about what is happening that no-one seems
to have pointed out to you yet (though Richard mentioned it in his
reply to CBFalconer). That is, that the '=' is also doing two
different things in your code above.

In the following line:

int *ptr2 = &b[0];

the = tells the computer what value ptr2 starts off with. This is
called an initialisation.

But in the following line:

ptr2 = &b[0];

the = sets a new value for ptr2. This is called an assignment.

There is not a lot of difference between the two, which is probably
why they have the same symbol, but it is important to be aware of the
difference, particularly if you are going to write in C++. One example
of the difference is that

Why would you bring up C++ when your example below is just as valid
for C?
 
J

jameskuyper

(e-mail address removed) wrote:
....
difference, particularly if you are going to write in C++. One example
of the difference is that

const int a = 3;

That works in both languages.
works, giving a a value to 3, which it will stay at, whereas

const int a;
a = 3;

That assignment statement isn't allowed in either language. The
difference between the two languages is that in C++, the definition
of 'a' is also an error. In C, that definition is an error if 'a' has
automatic storage duration, but not if it has static storage
duration. The following code is permitted at file scope in C, but not
in C++:

const int a; // Tentative definition.
// Some other code
const int a = 3; // Actual definition.

If no actual definition were provided, this would still be legal C; it
would be treated as equivalent to

const int a=0;
 
G

gw7rib

There's one other subtlety about what is happening that no-one seems
to have pointed out to you yet (though Richard mentioned it in his
reply to CBFalconer). That is, that the '=' is also doing two
different things in your code above.
In the following line:
int *ptr2 = &b[0];
the = tells the computer what value ptr2 starts off with. This is
called an initialisation.
But in the following line:
ptr2 = &b[0];
the = sets a new value for ptr2. This is called an assignment.
There is not a lot of difference between the two, which is probably
why they have the same symbol, but it is important to be aware of the
difference, particularly if you are going to write in C++. One example
of the difference is that

Why would you bring up C++ when your example below is just as valid
for C?

If he is going to stick to C, then he doesn't need to worry about the
difference very often - my example is one of the few times he does.

If, however, he is going to be writing in C++, and using classes, the
chances are that he will need to be aware of which constructor will
run when, and why he will probably need both an assignment operator
and a copy constructor. If he's clear now about the difference between
initialisation and asignment, that will help him.

Sorry if this wasn't clear - both you and James Kuyper have pulled me
up on this.
 

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

Members online

Forum statistics

Threads
473,772
Messages
2,569,588
Members
45,100
Latest member
MelodeeFaj
Top