2

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

2
  • 3
    Use %p to print a pointer. Commented Feb 5, 2014 at 20:54
  • 1
    It's int main(void), not void main(). (Some compilers happen to accept void main(), but there's no good reason to use it.) I'm curious: where did you get the idea that void main() is correct? Commented Feb 5, 2014 at 20:57

3 Answers 3

7

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

Sign up to request clarification or add additional context in comments.

15 Comments

There are other systems %ld specifier for a pointer will work besides Windows 64-bit
@chux: Can you name one? I bet they are fairly unusual.
Microchip made over billion processors in 2013. C is very popular here and many of those processors use 16-bit pointers and 32-bit long. Is billion enough to make them usual?
But that will still work. void *x; printf("x = %ld\n", (long) x);
@DietrichEpp: I think you mean (long) &x. Yes, it will work, but the result of converting a pointer to an integer type is implementation-defined -- and there's no guarantee that converting a pointer to long will not lose information. "%p" is specifically intended for printing pointer values (in an implementation-defined manner), and there's no much point in using some other method.
|
6
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.

5 Comments

@Stella: Thank you for that link. As I said, the author has some mistaken ideas about C. I haven't read the whole thing, but void main() is enough to suggest avoiding it. It refers to The C Programming Language by Kernighan & Ritchie; you won't find void main anywhere in that book. See also the comp.lang.c FAQ, questions 11.12a through 11.15. (It's possible that's the only serious error, but I wouldn't bet on it.)
@KeithThompson: While we are at this, can you recommend a good C tutorial?
@Grodriguez: Kernighan & Ritchie, "The C Programming Language", 2nd edition, is the classic -- though it assumes some programming experience. Section 18 of the comp.lang.c FAQ has some good links.
I was specifically looking for tutorials (I am compiling a list of useful resources for interns), so K&R is not really what I was after. But section 18 of the comp.lang.c FAQ is definitely helpful, thank you!
2

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

1 Comment

C90 implicitly declared functions. C99 dropped that rule, and made calling a function with no visible declaration a constraint violation, requiring a diagnostic. (gcc's warning satisfies that requirement.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.