By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,305 Members | 1,619 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,305 IT Pros & Developers. It's quick & easy.

Is not printf("%p", &i) correct?

P: n/a
Is parameter type conversion required for the 2nd argument on
printf("%p", (void *)&i); ?

But one would never call memcpy like:
memcpy((void *)pi, (void *)pj, sizeof *pj);
/*memcpy((void *)pi, (void *)pj, sizeof *pi);*/ /*size of what?*/

By the way, will the 3rd argument of memcpy follow the size of the 1st
or the 2nd argument? If it follows the size of the 1st argument,
unwanted data in the memory area pointed by the 2nd parameter will be
copied to the memory area pointed by the 1st parameter.

If it follows the 2nd one, the function will write to invalid memory
outside the area allocated to the 1st parameter.

lovecreatesbeauty

Jul 6 '06 #1
Share this Question
Share on Google+
10 Replies


P: n/a
lovecreatesbeauty said:
Is parameter type conversion required for the 2nd argument on
printf("%p", (void *)&i); ?
Yes. C does not supply automatic conversion of pointer values to void * when
they are arguments to the variadic part of a variadic function, because it
has no way of knowing whether such conversion is necessary.
But one would never call memcpy like:
memcpy((void *)pi, (void *)pj, sizeof *pj);
/*memcpy((void *)pi, (void *)pj, sizeof *pi);*/ /*size of what?*/
In this case, C knows that memcpy takes void *, because it is prototyped
accordingly. But printf is prototyped as int printf(const char *, ...), and
the ... can be freely interpreted as "I'm going to have to trust you on
this stuff". In other words, it's /your/ job to get the types right for
variadic function arguments.
By the way, will the 3rd argument of memcpy follow the size of the 1st
or the 2nd argument?
The third argument to memcpy dictates the number of bytes you wish to copy.
Only you know this. C doesn't. That's why you have to tell it.
If it follows the size of the 1st argument,
unwanted data in the memory area pointed by the 2nd parameter will be
copied to the memory area pointed by the 1st parameter.
Not if you specify the number of bytes that it is legal and desirable to
copy.
If it follows the 2nd one, the function will write to invalid memory
outside the area allocated to the 1st parameter.
Not if you specify the number of bytes that it is legal and desirable to
copy.

If you don't know how many bytes you want to copy, find out.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
Jul 6 '06 #2

P: n/a
lovecreatesbeauty wrote:
Is parameter type conversion required for the 2nd argument on
printf("%p", (void *)&i); ?
Yes, unless you don't mind making assumptions that are not guaranteed
by standard C. There are no implicit conversions for pointers in the
.... list of functions with a variable number of arguments.
But one would never call memcpy like:
memcpy((void *)pi, (void *)pj, sizeof *pj);
/*memcpy((void *)pi, (void *)pj, sizeof *pi);*/ /*size of what?*/
Here, the prototype for memcpy will ensure that pi and pj get converted
to void * and const void *.
By the way, will the 3rd argument of memcpy follow the size of the 1st
or the 2nd argument?
If the size of the two arguments is the same, it doesn't matter. If the
size is not the same, you have a special case and you will need to
check for yourself what you need to do.

Jul 6 '06 #3

P: n/a

Richard Heathfield wrote:
lovecreatesbeauty said:
Is parameter type conversion required for the 2nd argument on
printf("%p", (void *)&i); ?

Yes. C does not supply automatic conversion of pointer values to void * when
they are arguments to the variadic part of a variadic function, because it
has no way of knowing whether such conversion is necessary.
The conversion between the general pointer type "void *" and other
pointers is legal and automatically performed completely and performed
eventually, right?

Will C supply implied conversion for converting pointer type of
arguments (function call) to pointer type of parameter (declaration) of
type "void *" where there is not variable argument list?

The "%p" conversion specifier requires a corresponding value of type
void *. Can this "%p" act as the functionality of prototype and tell
the printf to convert the corresponding argument to type "void *".

lovecreatesbeauty

Jul 6 '06 #4

P: n/a
lovecreatesbeauty wrote:
Richard Heathfield wrote:
lovecreatesbeauty said:
Is parameter type conversion required for the 2nd argument on
printf("%p", (void *)&i); ?
Yes. C does not supply automatic conversion of pointer values to void * when
they are arguments to the variadic part of a variadic function, because it
has no way of knowing whether such conversion is necessary.

The conversion between the general pointer type "void *" and other
pointers is legal and automatically performed completely and performed
eventually, right?
It is legal, but if you mean this conversion happens always, you'd be
mistaken.The conversion depends on context.
Will C supply implied conversion for converting pointer type of
arguments (function call) to pointer type of parameter (declaration) of
type "void *" where there is not variable argument list?
This is a special case: See below:
N1124: 6.5.2.2 Function calls
....
[#7] If the expression that denotes the called function has a type
that does include a prototype, the arguments are implicitly
converted,as if by assignment, to the types of the corresponding
parameters,taking the type of each parameter to be the unqualified
version of its declared type.The ellipsis notation in a function
prototype declarator causes argument type conversion to stop after
the last declared parameter. The default argument promotions are
performed on trailing arguments.
The "%p" conversion specifier requires a corresponding value of type
void *. Can this "%p" act as the functionality of prototype and tell
the printf to convert the corresponding argument to type "void *".
No. The conversion specifier expects an argument of type void *,
it does not do a type conversion for you. For example, pointers
to functions cannot be converted to pointers to void.

Jul 6 '06 #5

P: n/a
>Richard Heathfield wrote:
>>C does not supply automatic conversion of pointer values to void * when
they are arguments to the variadic part of a variadic function, because it
has no way of knowing whether such conversion is necessary.
(Read that again, please. :-) )

In article <11**********************@l70g2000cwa.googlegroups .com>
lovecreatesbeauty <lo***************@gmail.comwrote:
>The conversion between the general pointer type "void *" and other
pointers is legal and automatically performed completely and performed
eventually, right?
Only under ordinary assignment, or conditions that are sufficiently
similar to ordinary assignment. That is:

void *vp;
int *ip;
... do something that sets ip to some value ...
vp = ip;

is OK because this is an ordinary assignment. A call to memcpy(),
of the form:

memcpy(&dst, ip, sizeof dst);

is probably OK (depending on the actual value in ip) because, in
the presence of a prototype, the prototyped arguments are sent through
"as if" by assignment. (But you do have to "#include <string.h>"
first.)
>Will C supply implied conversion for converting pointer type of
arguments (function call) to pointer type of parameter (declaration) of
type "void *" where there is not variable argument list?
Only in the presence of a prototype. That is:

extern void foo();

foo(ip);

does not convert the value in "ip" to "void *", because there is
no prototype for foo(). (This assumes there is no earlier declaration
for foo() that gave a prototype. If there was an earlier declaration,
see "composite type" in the C standards.)
>The "%p" conversion specifier requires a corresponding value of type
void *. Can this "%p" act as the functionality of prototype and tell
the printf to convert the corresponding argument to type "void *".
No:

char fmtA[] = "it's %d";
char fmtB[] = "it's %p";
char *fmt = rand() (RAND_MAX/2) ? fmtA : fmtB;

printf(fmt, ip);

Here, the call is incorrect no matter what, of course; but the
point is that the format is undecideable at compile time. It
could be even less predictable:

char fmtbuf[N];

gets(fmtbuf); /* this is bad, but we're about to be even worse: */
printf(fmtbuf, ip);

As a result, compilers are not *required* to check the format string
at all, and many do not. (GCC has "raised the bar" by actually
checking when it can, so now at least a *few* other compilers do
similar checking.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jul 6 '06 #6

P: n/a
lovecreatesbeauty wrote:
Richard Heathfield wrote:
>lovecreatesbeauty said:
>>Is parameter type conversion required for the 2nd argument on
printf("%p", (void *)&i); ?
Yes. C does not supply automatic conversion of pointer values to void * when
they are arguments to the variadic part of a variadic function, because it
has no way of knowing whether such conversion is necessary.

The conversion between the general pointer type "void *" and other
pointers is legal and automatically performed completely and performed
eventually, right?
Yes, except in a variable argument list.
Will C supply implied conversion for converting pointer type of
arguments (function call) to pointer type of parameter (declaration) of
type "void *" where there is not variable argument list?
Yes.
The "%p" conversion specifier requires a corresponding value of type
void *. Can this "%p" act as the functionality of prototype and tell
the printf to convert the corresponding argument to type "void *".
No, that is why you need the cast when using %p in printf.

Jul 6 '06 #7

P: n/a
On 5 Jul 2006 23:04:56 -0700, "lovecreatesbeauty"
<lo***************@gmail.comwrote:
>
Richard Heathfield wrote:
>lovecreatesbeauty said:
Is parameter type conversion required for the 2nd argument on
printf("%p", (void *)&i); ?

Yes. C does not supply automatic conversion of pointer values to void * when
they are arguments to the variadic part of a variadic function, because it
has no way of knowing whether such conversion is necessary.

The conversion between the general pointer type "void *" and other
pointers is legal and automatically performed completely and performed
eventually, right?
Yes.
>Will C supply implied conversion for converting pointer type of
arguments (function call) to pointer type of parameter (declaration) of
type "void *" where there is not variable argument list?
Yes.
>The "%p" conversion specifier requires a corresponding value of type
void *. Can this "%p" act as the functionality of prototype and tell
the printf to convert the corresponding argument to type "void *".
I believe it can, if the implementation documents such behavior. But
you probably won't find such an implementation, and furthermore, the
code would not be portable.

Another option is to add this feature to a future revision of the C
Standard. But that will never happen. And even if it did happen, you'd
probably be in the same boat as if your specific implementation had
implemented it.

That's because recent history has shown that compilers and people
don't march to the same beat as that of the latest and greatest C
Standard. To wit, C99 has been out for over 7 years, but many or
arguably most compilers have not been updated to conform to this
revision and many people still consider "portable" code as that which
conforms to the C90 Standard only. Code such as the following,
although it conforms to the current C Standard, often provokes a
response with a flare of non-portability consequence:

#include <stdio.h>
int main(void)
{
// print a 5
printf("%d\n", 5);
int ii = 6;
// print a variable
printf("%d\n", ii);
return 0;
}

You should always ensure that pointer arguments to printf() are
(void*) (possibly through a cast) if the conversion specifier is "%p".
That's a golden rule that should never be broken.

--
jay
Jul 6 '06 #8

P: n/a
jaysome <ja*****@spamcop.netwrites:
On 5 Jul 2006 23:04:56 -0700, "lovecreatesbeauty"
<lo***************@gmail.comwrote:
[...]
>>The "%p" conversion specifier requires a corresponding value of type
void *. Can this "%p" act as the functionality of prototype and tell
the printf to convert the corresponding argument to type "void *".

I believe it can, if the implementation documents such behavior. But
you probably won't find such an implementation, and furthermore, the
code would not be portable.

Another option is to add this feature to a future revision of the C
Standard. But that will never happen. And even if it did happen, you'd
probably be in the same boat as if your specific implementation had
implemented it.
It will never happen because the compiler would need to know at
compilation time whether and how to do the conversion, and the format
string isn't necessarily known until run time.

For example:

char *format;
char *p = /* ... */;
if (some_condition) {
format = "pointer = %p\n";
}
else {
format = "string = %s\n";
}
printf(format, p);

As it happens, the standard requires char* and void* to have the same
representation, but the same situation can arise for other variadic
functions.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jul 6 '06 #9

P: n/a
lovecreatesbeauty wrote:
...
The conversion between the general pointer type "void *" and other
pointers is legal and automatically performed completely and performed
eventually, right?
Yes. The conversion is performed by the core language features. In order
to perform it the compiler has to know both source and destination type
at compile time. This requirement is met in your 'memcpy' examples.
Will C supply implied conversion for converting pointer type of
arguments (function call) to pointer type of parameter (declaration) of
type "void *" where there is not variable argument list?
Yes. In this case parameter types and argument types are known at
compile time and C will perform the conversion.
The "%p" conversion specifier requires a corresponding value of type
void *. Can this "%p" act as the functionality of prototype and tell
the printf to convert the corresponding argument to type "void *".
Firstly, in general case it cannot be done outside 'printf' (as it
happens with typed parameters), since, once again, such conversion is a
core language feature, which means that the converting code (if any) is
implemented by the compiler at compile time. 'printf' function with its
specification is not a core language feature. It is a library function.
The compiler has absolutely no idea about the meaning of the format
string in 'printf' (and '%p' specifier in particular). For this reason,
no meaningful conversion can be performed.

Of course, language specification does not forbid anyone to go as far as
creating a compiler that does recognize the format specifiers in
'printf' and does perform the proper conversion, but that would become a
specific non-portable feature of that particular compiler. Not very useful.

Secondly, 'printf' itself cannot perform the proper conversion
internally, since, once again, in order to perform a conversion like
this both source and destination type have to be known. In general case
inside 'printf' the source type of the value is not known and cannot be
known. Hence no conversion is possible.

--
Best regards,
Andrey Tarasevich
Jul 6 '06 #10

P: n/a
jaysome wrote:
On 5 Jul 2006 23:04:56 -0700, "lovecreatesbeauty"
<lo***************@gmail.comwrote:
The "%p" conversion specifier requires a corresponding value of type
void *. Can this "%p" act as the functionality of prototype and tell
the printf to convert the corresponding argument to type "void *".

I believe it can, if the implementation documents such behavior.
Keep in mind though that the below is a strictly conforming program,
and a conforming implementation is not allowed to reject it. (However,
any compiler may give any warning for any code, valid or invalid, of
course.)

#include <stdio.h>
int main(void) {
if(0) printf("%p", 1);
}

Jul 6 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.