Trouble-lling
Trouble-lling

Reputation: 343

Using printf with a pointer to float gives an error

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

Upvotes: 2

Views: 7999

Answers (3)

Dietrich Epp
Dietrich Epp

Reputation: 213698

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

Upvotes: 7

user3264405
user3264405

Reputation: 330

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

Upvotes: 2

Keith Thompson
Keith Thompson

Reputation: 263587

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.

Upvotes: 6

Related Questions