473,394 Members | 1,794 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,394 software developers and data experts.

Pointer to pointer conversion

Hello. When I practice pointers, I write code like the following:
int *pn1;
void **pv = (void **)&pn1;
*pv = malloc(sizeof(int));
*pn1 = 1;

It seems to work. But when I consult n1124(the draft c99 standard with
tc2), in section 6.3.2.3/7, it says:
"A pointer to an object or incomplete type may be converted to a
pointer to a different
object or incomplete type. If the resulting pointer is not correctly
aligned for the
pointed-to type, the behavior is undefined."

It seems this statement fits the above code. Since no document says
whether (void **) is properly aligned for (int **), is the above code
potentially dangerous?
Jun 27 '08 #1
9 1556
WaterWalk wrote:
Hello. When I practice pointers, I write code like the following:
int *pn1;
void **pv = (void **)&pn1;
*pv = malloc(sizeof(int));
*pn1 = 1;

It seems to work. But when I consult n1124(the draft c99 standard with
tc2), in section 6.3.2.3/7, it says:
"A pointer to an object or incomplete type may be converted to a
pointer to a different
object or incomplete type. If the resulting pointer is not correctly
aligned for the
pointed-to type, the behavior is undefined."
Yes, but at 6.3.2.2/1, it says:

6.3.2.3 Pointers
1 A pointer to void may be converted to or from a pointer to any
incomplete or object type. A pointer to any incomplete or object
type may be converted to a pointer to void and back again; the
result shall compare equal to the original pointer.

the cast (void **) on &pn1 is not even necessary.

Moreover, I don't see the point of using pv to allocate room for pn1.

Why not just

pn1 = malloc(sizeof(int));

?
>
It seems this statement fits the above code. Since no document says
whether (void **) is properly aligned for (int **), is the above code
potentially dangerous?

--
Pietro Cerutti
Jun 27 '08 #2
Pietro Cerutti wrote:
WaterWalk wrote:
>Hello. When I practice pointers, I write code like the following:
int *pn1;
void **pv = (void **)&pn1;
*pv = malloc(sizeof(int));
*pn1 = 1;

It seems to work. But when I consult n1124(the draft c99 standard with
tc2), in section 6.3.2.3/7, it says:
"A pointer to an object or incomplete type may be converted to a
pointer to a different
object or incomplete type. If the resulting pointer is not correctly
aligned for the
pointed-to type, the behavior is undefined."

Yes, but at 6.3.2.2/1, it says:

6.3.2.3 Pointers
1 A pointer to void may be converted to or from a pointer to any
incomplete or object type. A pointer to any incomplete or object
type may be converted to a pointer to void and back again; the
result shall compare equal to the original pointer.

the cast (void **) on &pn1 is not even necessary.

Moreover, I don't see the point of using pv to allocate room for pn1.

Why not just

pn1 = malloc(sizeof(int));
Even better:

pn1 = malloc(sizeof *pn1);
Jun 27 '08 #3
Pietro Cerutti <gahr_SPAM_gahr_ME_chsaid:
WaterWalk wrote:
>Hello. When I practice pointers, I write code like the following:
int *pn1;
void **pv = (void **)&pn1;
*pv = malloc(sizeof(int));
*pn1 = 1;

It seems to work. But when I consult n1124(the draft c99 standard with
tc2), in section 6.3.2.3/7, it says:
"A pointer to an object or incomplete type may be converted to a
pointer to a different
object or incomplete type. If the resulting pointer is not correctly
aligned for the
pointed-to type, the behavior is undefined."

Yes, but at 6.3.2.2/1, it says:

6.3.2.3 Pointers
1 A pointer to void may be converted to or from a pointer to any
incomplete or object type. A pointer to any incomplete or object
type may be converted to a pointer to void and back again; the
result shall compare equal to the original pointer.

the cast (void **) on &pn1 is not even necessary.
void ** != void *

--
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
Jun 27 '08 #4
WaterWalk said:
Hello. When I practice pointers, I write code like the following:
int *pn1;
void **pv = (void **)&pn1;
Unwise.
*pv = malloc(sizeof(int));
Unwiser.
*pn1 = 1;

It seems to work. But when I consult n1124(the draft c99 standard with
tc2), in section 6.3.2.3/7, it says:
"A pointer to an object or incomplete type may be converted to a
pointer to a different
object or incomplete type. If the resulting pointer is not correctly
aligned for the
pointed-to type, the behavior is undefined."

It seems this statement fits the above code. Since no document says
whether (void **) is properly aligned for (int **), is the above code
potentially dangerous?
Yes, and for precisely the reason you state. The guarantee that the C
Standard gives for void * does not extend to void **.

--
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
Jun 27 '08 #5
Pietro Cerutti wrote:
WaterWalk wrote:
>Hello. When I practice pointers, I write code like the following:
int *pn1;
void **pv = (void **)&pn1;
*pv = malloc(sizeof(int));
*pn1 = 1;

It seems to work. But when I consult n1124(the draft c99 standard with
tc2), in section 6.3.2.3/7, it says:
"A pointer to an object or incomplete type may be converted to a
pointer to a different
object or incomplete type. If the resulting pointer is not correctly
aligned for the
pointed-to type, the behavior is undefined."

Yes, but at 6.3.2.2/1, it says:

6.3.2.3 Pointers
1 A pointer to void may be converted to or from a pointer to any
incomplete or object type. A pointer to any incomplete or object
type may be converted to a pointer to void and back again; the
result shall compare equal to the original pointer.
Which variable in the sample code is a pointer to void?
(Hint: None of them is a pointer to void, so the paragraph
you quote does not apply.)
the cast (void **) on &pn1 is not even necessary.
If the cast is omitted, the compiler is required to emit
a diagnostic message. There is no implicit conversion from
`int**' (the type of `&pn1') to `void**'.

With the cast in place, no diagnostic is required but the
behavior is undefined. See Question 4.9 in the comp.lang.c
Frequently Asked Questions (FAQ) list, <http://www.c-faq.com/>.
>It seems this statement fits the above code. Since no document says
whether (void **) is properly aligned for (int **), is the above code
potentially dangerous?
Yes, and not only because of alignment issues. `void*'
and `int*' can have different representations and even different
sizes. On machines where this is true, `void*' is usually wider
than `int*', so the assignment `*pv = malloc(...)' could step
on memory adjacent to but not part of `pn1'.

The fact that `void*' can be used as a "generic pointer"
leads some to think that `void**' is a "generic pointer-to-
pointer," but there is no such animal in C.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Jun 27 '08 #6
Eric Sosman wrote:
Pietro Cerutti wrote:
>WaterWalk wrote:
>>Hello. When I practice pointers, I write code like the following:
int *pn1;
void **pv = (void **)&pn1;
*pv = malloc(sizeof(int));
*pn1 = 1;

It seems to work. But when I consult n1124(the draft c99 standard with
tc2), in section 6.3.2.3/7, it says:
"A pointer to an object or incomplete type may be converted to a
pointer to a different
object or incomplete type. If the resulting pointer is not correctly
aligned for the
pointed-to type, the behavior is undefined."

Yes, but at 6.3.2.2/1, it says:

6.3.2.3 Pointers
1 A pointer to void may be converted to or from a pointer to any
incomplete or object type. A pointer to any incomplete or object
type may be converted to a pointer to void and back again; the
result shall compare equal to the original pointer.

Which variable in the sample code is a pointer to void?
(Hint: None of them is a pointer to void, so the paragraph
you quote does not apply.)
>the cast (void **) on &pn1 is not even necessary.

If the cast is omitted, the compiler is required to emit
a diagnostic message. There is no implicit conversion from
`int**' (the type of `&pn1') to `void**'.

With the cast in place, no diagnostic is required but the
behavior is undefined. See Question 4.9 in the comp.lang.c
Frequently Asked Questions (FAQ) list, <http://www.c-faq.com/>.
>>It seems this statement fits the above code. Since no document says
whether (void **) is properly aligned for (int **), is the above code
potentially dangerous?

Yes, and not only because of alignment issues. `void*'
and `int*' can have different representations and even different
sizes. On machines where this is true, `void*' is usually wider
than `int*', so the assignment `*pv = malloc(...)' could step
on memory adjacent to but not part of `pn1'.

The fact that `void*' can be used as a "generic pointer"
leads some to think that `void**' is a "generic pointer-to-
pointer," but there is no such animal in C.
Me being one of those :-(

Thanks for clarifying this point, sorry WaterWalk for the wrong advice.

--
Pietro Cerutti
Jun 27 '08 #7
Eric Sosman <es*****@ieee-dot-org.invalidwrites:
[...]
The fact that `void*' can be used as a "generic pointer"
leads some to think that `void**' is a "generic pointer-to-
pointer," but there is no such animal in C.
There is, sort of. You can use void* as a "generic
pointer-to-pointer" (but if you inadvertently assign a
pointer-to-something-else to it, the compiler won't catch your error).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #8
Keith Thompson wrote:
Eric Sosman <es*****@ieee-dot-org.invalidwrites:
[...]
> The fact that `void*' can be used as a "generic pointer"
leads some to think that `void**' is a "generic pointer-to-
pointer," but there is no such animal in C.

There is, sort of. You can use void* as a "generic
pointer-to-pointer" (but if you inadvertently assign a
pointer-to-something-else to it, the compiler won't catch your error).
Since void* can point to any data, it can point to any
pointer, yes. But that's not the sense I was trying to
convey with the phrase "generic pointer-to-pointer," an
admittedly unofficial phrase but one that's also used by
the FAQ.

Here's what the FAQ and I mean by saying that C lacks
a "generic pointer-to-pointer:" We mean that there is no
type that can point at arbitrary pointer objects and can
manipulate those pointed-to objects as pointers. This is
the bane of "generic" linked-list packages, hash-table
packages, and so on, the usual unsatisfactory dodge being
to deal in `void*' pointers and document VERY LOUDLY that
they must actually be pointers to struct types.

--
Er*********@sun.com
Jun 27 '08 #9
On May 22, 9:19 pm, WaterWalk <toolmas...@163.comwrote:
Hello. When I practice pointers, I write code like the following:
int *pn1;
void **pv = (void **)&pn1;
*pv = malloc(sizeof(int));
*pn1 = 1;

It seems to work. But when I consult n1124(the draft c99 standard with
tc2), in section 6.3.2.3/7, it says:
"A pointer to an object or incomplete type may be converted to a
pointer to a different
object or incomplete type. If the resulting pointer is not correctly
aligned for the
pointed-to type, the behavior is undefined."

It seems this statement fits the above code. Since no document says
whether (void **) is properly aligned for (int **), is the above code
potentially dangerous?
Thank you all. Now I know better this problem.
Jun 27 '08 #10

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

Similar topics

8
by: chessc4c6 | last post by:
The program below creates a char pointer call charPtr...... i then declare an char array string "Good Luck" When i assign charPtr = string, I expect an error. However, It actually runs and...
11
by: x-pander | last post by:
given the code: <file: c.c> typedef int quad_t; void w0(int *r, const quad_t *p) { *r = (*p); }
16
by: junky_fellow | last post by:
According to Section A6.6 Pointers and Integers (k & R) " A pointer to one type may be converted to a pointer to another type. The resulting pointer may cause addressing exceptions if the...
10
by: junky_fellow | last post by:
K&R say that, It is guaranteed that 1) a pointer to an object may be converted to a pointer to an object whose type requires less or equally strict storage alignment and 2) back again without...
204
by: Alexei A. Frounze | last post by:
Hi all, I have a question regarding the gcc behavior (gcc version 3.3.4). On the following test program it emits a warning: #include <stdio.h> int aInt2 = {0,1,2,4,9,16}; int aInt3 =...
28
by: Wonder | last post by:
Hello, I'm confused by the pointer definition such as int *(p); It seems if the parenthesis close p, it defines only 3 integers. The star is just useless. It can be showed by my program: ...
48
by: yezi | last post by:
Hi, all: I want to record some memory pointer returned from malloc, is possible the code like below? int memo_index; int i,j; char *tmp; for (i=0;i<10;i++){
49
by: elmar | last post by:
Hi Clers, If I look at my ~200000 lines of C code programmed over the past 15 years, there is one annoying thing in this smart language, which somehow reduces the 'beauty' of the source code...
6
by: Lighter | last post by:
How to read "The lvalue-to-rvalue, array-to-pointer, and function-to- pointer standard conversionsare not applied to the left expressions"? In 5.18 Comma operator of the C++ standard, there is a...
8
by: tfelb | last post by:
Hey group! I have 2 questions. I saw functions with char *dst = (char *)src. In that case if I remember what I've learned I assign (an) (the) address of src to dst. Right? But I can assign...
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: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

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.