Using printf with a pointer to float gives an error - c

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;
}

Related

C Pointer Question 'int', but argument 2 has type 'int **'

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.

Need for casting to generic pointer [duplicate]

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...

Am I losing information with this printf()?

In Expert C Programming, there is an exercise on page 146 that is supposed to illustrate how a typical Unix OS allocates various segments of an a.out file into various memory segments for execution.
The "starter" code is:
main () {
int i;
printf("The stack top is near %#X\n", &i);
}
The compiler warns, but does not error, the use of %X with &i:
warning: format ‘%X’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int *’ [-Wformat]
As a newcomer to memory layouts and hex addresses, I am just wondering if the recommended formatting is not representing the desired information in full? I searched around but couldn't find anything definitive--for instance, I read about using the %p format cue, but it wasn't clear if that was necessary for this case.
Also, it seems doubtful that this sacred C book would make such an error, so I assume it is an extraneous warning for this use case, but I would like to be sure.
int i;
printf("The stack top is near %#X\n", &i);
This is undefined behavior. X conversion specifier requires an argument of type unsigned int but &i is of type pointer to int. C does not require an implementation to abort translation in case of undefined behavior but an abort of translation is allowed by C.
To print a pointer value use p conversion specifier:
int i;
printf("The stack top is near %p\n", (void *) &i);

Warnings in a very basic Pointer Program in C

I've just started with pointers in c. This program gives the desired output but I am getting the below warnings when I compile it, What am I doing wrong?
pointer.c:3: warning: initialization makes pointer from integer without a cast
pointer.c:5: warning: incompatible implicit declaration of built-in function ‘printf’
pointer.c:8: warning: assignment from incompatible pointer type
pointer.c:12: warning: assignment makes pointer from integer without a cast
And my code is:
int main (int argc, char *argv[])
{
int *x=2, *ampx, *starampx, starx;
printf("x=");
printf("%d\n",x);
ampx=&x;
printf("&x=");
printf("%d\n",&x);
starampx=*ampx;
printf("*&x=");
printf("%d\n",starampx);
return 0;
}
Here is why:
initialization makes pointer from integer without a cast - int *x = 2, ... should be int x = 2, ...
incompatible implicit declaration of built-in function ‘printf’ - You need to add an #include <stdio.h> line at the top
assignment from incompatible pointer type - This will be fixed by the #1 change
assignment makes pointer from integer without a cast - *starampx should be starampx in the declaration.
In addition, printing pointers should be done with %p specifier, not %d:
printf("%p\n",&x);
Here is your fixed program on ideone: link.
int *x=2
is actually causing your program to have undefined behavior. It tells the compiler to point at an address 2, which may or may not be valid and derferencing the pointer will causes an undefined behavior.
Whenever you are using pointers, You need to make the pointer point to a valid memory big enough to store a int before you can store anything. So you either need:
int i = 2;
int *x = &i;
or you simply use:
int x = 2;
Considering, how you use x later in the program the latter is what you need.
You need to include stdio.h which tells the compiler that printf is an standard c library function.
In your code, in this statement, you have a problem.
int *x=2, *ampx, *starampx, starx;
^ ^
| |
*x is a pointer. To store the value of 2, you would need to allocate space for the same. Instead of the current implementation, please try with
int x=2, *ampx, starampx, starx;

Pointer will not work in printf()

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...

Resources