Having an issue with printing a pointer out. Every time I try and compile the program below i get the following error:
pointers.c:11: warning: format ‘%p’ expects type ‘void *’, but argument 2 has type ‘int *’
I'm obviously missing something simple here, but from other examles of similar code that I have seen, this should be working.
Here's the code, any help would be great!
#include <stdio.h>
int main(void)
{
int x = 99;
int *pt1;
pt1 = &x;
printf("Value at p1: %d\n", *pt1);
printf("Address of p1: %p\n", pt1);
return 0;
}
Simply cast your int pointer to a void one:
printf( "Address of p1: %p\n", ( void * )pt1 );
Your code is safe, but you are compiling with the -Wformat warning flag, that will type check the calls to printf() and scanf().
Note that you get a simple warning. Your code will probably execute as expected.
The "%p" conversion specifier to printf expects a void* argument; pt1 is of type int*.
The warning is good because int* and void* may, on strange implementations, have different sizes or bit patterns or something.
Convert the int* to a void* with a cast ...
printf("%p\n", (void*)pt1);
... and all will be good, even on strange implementations.
In this case, the compiler is just a bit overeager with the warnings. Your code is perfectly safe, you can optionally remove the warning with:
printf("Address of p1: %p\n", (void *) pt1);
The message says it all, but it's just a warning not an error per se:
printf("Address of p1: %p\n", (void*)pt1);
This worked just fine for me:
printf("Pointer address: %p.", pxy);
You don't need to cast it as anything, unless you wanted to...
Related
I am currently doing pointers. I have been programming for a long time, but not in C/C++. With that being said, my pointer knowledge is abysmal.
Currently, I am following a guide on YouTube and he prints the code below.
int main() {
int a = 5;
int *p;
p = &a;
printf("%d\n", p);
}
This prints successfully for him, and he sees a memory location. For me, I see the error
warning: format '%d' expects argument of type 'int', but argument 2 has type 'int *'
From this, I expect I need to put an & in front of the p to make it print the value. But then I receive this error,
int main() {
int a = 5;
int *p;
p = &a;
printf("%d\n", &p);
}
'int', but argument 2 has type 'int **'
Where is the hole in my knowledge? Any key tips or strategies when working with this, I don't know why I find this so abstract.
Thanks,
I was expecting the value to print as expected, but instead am greeted with the error.
%d is the wrong format specifier for pointers. That may work on a more lenient or noncompliant implementation, but you should use %p to print pointer values.
Warnings are not errors. You're receiving a warning, which is not stopping your program from working, because the print specifier %d (ie printf("%d")) is for displaying integers, and you're giving it a non-integer argument of type int*.
The problem here is not with the argument, it's with the print specifier. Your attempt at a fix just changes the int* to an int**, which still does not match the format specifier %d. Use %p instead, which is the specifier for pointers, and will fix the warning, and print the address in hexadecimal notation.
You could also suppress the warning with a series of explicit casts from int* to int, but integer representations of memory addresses are generally much less used than hexadecimal representations in the first place.
Note that using wrong format specifier in printf() lead to undefined behaviour1).
The correct format specifier to print a pointer is %p format specifier.
Remember, format specifier %p expect that the argument shall be a pointer to void, so you should type cast pointer argument to void *. The correct statement to print pointer p would be:
printf("%p\n", (void *)p);
C11#7.21.6.1p9 [emphasis added]
9 If a conversion specification is invalid, the behavior is undefined.282) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
int main()
{
int a;
int* b;
a = 40;
b = &a;
printf("the address of a is %p, and the value of a is %d \n",&a, a);
return 0;
}
I find that both (void*)&a and &a print the same thing. So why do people still add (void*)? Is it just a habit?
You use specifier %p to print address stored in pointer, and this format specifier expects type to be void * . And as &a is of type int * , cast void * is used .
The printf() format specifier %p expects a void* type pointer. Since what you are passing might not be a void* type pointer, and the standard does not mandate for all pointers to have the same format, is is important that you cast a pointer to void* before passing it to printf.
For instance:
int* a = malloc(sizeof(int));
printf("a is %p",(void*)a);
Is done as best practice incase int* and void* are not similar
C Standard says that using an incorrect specifier for an argument in printf will result in undefined behavior.
7.21.6.1 The fprintf function
If a conversion specification is invalid, the behavior is undefined. 282) If any argument is
not the correct type for the corresponding conversion specification, the behavior is
undefined.
Since pointer to int is not the same type as pointer to void, and %p may only be used for a pointer to void and even if some other rules says that any pointer may be converted to pointer to void and back, that doesn't change the fact that the behavior is undefined, because of the quoted rule.
Firstly, different pointer types are not necessarily interchangable.
Secondly, for varargs no implicit conversion takes place as the compiler does not know the expected type.
When I'm writing this code:
#include <stdio.h>
int main()
{
printf("%p\n",main);
printf("%d\n",main);
return 0;
}
my compiler shows me this output:
00401318
4199192
I'm interested to know what actually is printed. I googled my question, but have found nothing. :(
Thanks in advance.
This is not well-defined.
You're using %p, which expects an argument of type void *, but you're actually passing it a value of type int (*)(), i.e. your (also badly defined) main() function.
You cannot portably cast a function pointer to void *, so your code can never be correct.
On most typicaly systems, sizeof (void *) == sizeof main, so you simply get the value interpreted as a void * which probably will simply be the address of the function.
Passing a function address to printf() with a format specifier of %d is even worse, since it's quite likely that sizeof (int) != sizeof main and then you get undefined behavior.
This is not good code.
main is a function pointer of type int(*)(void)
printf("%p\n", main);
You are printing the address of that pointer, which, on your platform has been successfully cast to a void*. This will be fine if sizeof(main) == sizeof(void*).
printf("%d\n", main);
This will give you undefined behaviour since %d is not a good format specifier for a pointer type.
When I try to compile this code:
void main()
{
float x;
x=6.5;
printf("Value of x is %f, address of x %ld\n", x, &x);
}
it gives me this error:
pruebaso.c: In function ‘main’:
pruebaso.c:5:9: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
printf("Value of x is %f, address of x %ld\n", x, &x);
^
pruebaso.c:5:9: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 3 has type ‘float *’ [-Wformat=]
I've seen in another forum the solution is to make a cast to a void pointer first:
http://www.linuxquestions.org/questions/programming-9/beginning-c-programming-how-to-print-memory-locations-printf-conversion-number-927305/
But making this change,
printf("Value of x is %f, address of x %ld\n", (double)x, (void *)&x);
now gives me a warning:
pruebaso.c: In function ‘main’:
pruebaso.c:5:9: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
printf("Value of x is %f, address of x %ld\n", (double)x, (void *)&x);
^
pruebaso.c:5:9: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 3 has type ‘void *’ [-Wformat=]
Could someone explain me how could I solve it without getting a warning?
Thank you
You need to include <stdio.h> to suppress the first warning and use a cast to void * and use %p to suppress the second warning.
In C90, using printf() without <stdio.h> invokes undefined behavior because the implicit declaration will not match the actual declaration, since printf() is variadic. (Using fputs() would be okay, by comparison.) In C99, implicit declarations are not allowed but GCC allows you to compile such code anyway.
#include <stdio.h>
int main(void)
{
float x = 6.5;
printf("Value of x is %f, address of x %p\n", x, (void *) &x);
}
The %p format specifier is used for printing pointers. Technically, it must be used with a char * or void * pointer. On modern systems, this will not affect the result; but passing other pointer types to %p will technically invoke undefined behavior (which is bad).
The %ld format in your code is wrong, even though it will work on most systems. First, it takes a long argument, which requires a cast (even though the cast will only make a difference on a few systems). Second, even if you add the cast, not all information in the pointer is guaranteed to remain (it might chop off bits or do something else). In practice, 64-bit Windows systems are the only systems where a cast to long chops of bits and the cast works fine everywhere else.
So use %p and cast to void *.
void main()
{
float x;
x=6.5;
printf("Value of x is %f, address of x %ld\n", x, &x);
}
The immediate problem is that you're missing the required #include <stdio.h>, but that's not the only problem with your code. Some of these things are errors that you can probably get away with (compilers may not complain, and may generate code that does what you expect), but there's no reason not to do it right.
#include <stdio.h>
int main(void)
{
float x;
x = 6.5;
printf("Value of x is %f, address of x %p\n", x, (void*)&x);
}
To explain the changes I made:
#include <stdio.h> is required for any program that calls printf. More precisely, a declaration of printf is required, and <stdio.h> provides it. (In principle you could write your own declaration instead, but there's no good reason to do so.)
The correct definition of main is int main(void). void main() may be accepted by some compilers, but it's useful mostly as a way to detect bad books. If you're using a book that tells you to use void main(), its author does not know the language very well, and may have given you other misinformation. Find a better book. (Caveat: void main(), or more likely void main(void) might actually be the preferred implementation-defined form for some embedded systems. but you're probably not using such a system.)
The "%ld" format requires an argument of type long int. The only correct format for printing a pointer value is "%p". Since "%p" requires an argument of type void*, you should explicitly cast your pointer value to void*. Omitting the cast is likely to "work", but float* and void* are distinct types, and are not guaranteed to have the same representation or to be passed to functions in the same way.
C implicitly declares functions if you use them before defining it, which caused the error " incompatible implicit declaration of built-in function ‘printf’".
To fix this, add #include <stdio.h> at the top of the file (this copies over the header file that includes a declaration for printf.
The second thing issue is that you should use %p to print pointers.
The resulting code is
#include <stdio.h>
int main(void)
{
float x;
x=6.5;
printf("Value of x is %f, address of x %p\n", x, (void *) &x);
return 0;
}
Having an issue with printing a pointer out. Every time I try and compile the program below i get the following error:
pointers.c:11: warning: format ‘%p’ expects type ‘void *’, but argument 2 has type ‘int *’
I'm obviously missing something simple here, but from other examles of similar code that I have seen, this should be working.
Here's the code, any help would be great!
#include <stdio.h>
int main(void)
{
int x = 99;
int *pt1;
pt1 = &x;
printf("Value at p1: %d\n", *pt1);
printf("Address of p1: %p\n", pt1);
return 0;
}
Simply cast your int pointer to a void one:
printf( "Address of p1: %p\n", ( void * )pt1 );
Your code is safe, but you are compiling with the -Wformat warning flag, that will type check the calls to printf() and scanf().
Note that you get a simple warning. Your code will probably execute as expected.
The "%p" conversion specifier to printf expects a void* argument; pt1 is of type int*.
The warning is good because int* and void* may, on strange implementations, have different sizes or bit patterns or something.
Convert the int* to a void* with a cast ...
printf("%p\n", (void*)pt1);
... and all will be good, even on strange implementations.
In this case, the compiler is just a bit overeager with the warnings. Your code is perfectly safe, you can optionally remove the warning with:
printf("Address of p1: %p\n", (void *) pt1);
The message says it all, but it's just a warning not an error per se:
printf("Address of p1: %p\n", (void*)pt1);
This worked just fine for me:
printf("Pointer address: %p.", pxy);
You don't need to cast it as anything, unless you wanted to...