Example pointer in C not working [duplicate] - c

This question already has answers here:
How to print variable addresses in C?
(5 answers)
Closed 7 years ago.
i'm new learning C, and learning pointer right now,i study from this website, but this code give me an error : pointer.c: In function ‘main’:
pointer.c:6:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("Address: %d",&var); //Notice, the ampersand(&) before var.
i compile it with : gcc -o pointer pointer.c
/* Example to demonstrate use of reference operator in C programming. */
#include <stdio.h>
int main(){
int var = 5;
printf("Value: %d\n",var);
printf("Address: %d",&var); //Notice, the ampersand(&) before var.
return 0;
}
http://www.programiz.com/c-programming/c-pointers

You're trying to print the address of var as if it was a signed integer, which it isn't. It's a pointer, and might have a different size than an integer.
Passing values of mismatching types to printf() invokes undefined behavior, which is why the compiler is issuing a friendly warning.
You should use %p to format it, and cast the value to (void *) to comply with the C standard:
printf("Address: %p\n", (void *) &var);

Please use correct format specifiers for each data type. Addresses are specified by %p.

It's better if you use %p to print a pointer. From the specification:
p The argument shall be a pointer to void. The value of the pointer is
converted to a sequence of printing characters, in an
implementation-defined manner.
Don't forget the cast: printf("Address: %p\n",(void*)&var);

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.

Address of variables in C using %p

For example,
int a = 6;
printf("%p", &a);
this would print the address of the pointer of a right?
but what if we print without &?
int a = 6;
printf("%p", a);
Can someone please tell me what it prints out?
This is undefined behavior, because %p expects a void*
printf("%p", a);
Adding an explicit conversion is allowed, but the behavior is implementation-defined:
printf("%p", (void*)a);
"Implementation-defined" means that the compiler is free to do whatever it wants when converting an int to void*. See this Q&A for exact quotes from the standard.
In many implementations you would see a pointer assigned the numeric value of int (demo 1). Other implementations would warn you that the behavior is meaningless. If you treat warnings as errors, the code would fail to compile (demo 2).
According to the C standard, it's undefined behavior to send wrong matching type argument to printf(). And int != void *, so it's undefined behavior.
Each of the following statements applies unless explicitly stated otherwise in the detailed descriptions that follow: If an argument to a function has an invalid value (such as a value outside the domain of the function, or a pointer outside the address space of the program, or a null pointer, or a pointer to non-modifiable storage when the corresponding parameter is not const-qualified) or a type (after promotion) not expected by a function with variable number of arguments, the behavior is undefined.
Source
By the way, that why you should write printf("%p", (void *)&a);
warning: format specifies type 'void *' but the argument has type 'int *' [-Wformat-pedantic]
printf("%p", &a);
~~ ^~

(1)In function ‘main’:(2) warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat] [duplicate]

This question already has answers here:
Correct format specifier to print pointer or address?
(5 answers)
Closed 6 years ago.
What is wrong with my code?
#include<stdio.h>
int main(void){
int a;
int *p;
p=&a;
printf("%d\n",p);
}
%d format specifier in printf() expects an int argument. In your code you're passing a int *. You need to either
Dereference the pointer to get an int type, if you want to print the value stored in the memory location pointed by the pointer.
use %p format specifier and cast the argument to void *, if you want to print the pointer.
It invokes undefined behavior to pass a wrong type of argument to any format specifier.

Why does %u %d not work on UNIX/LINUX for printing addresses [duplicate]

This question already has answers here:
difference between printing a memory address using %u and %d in C?
(5 answers)
Closed 7 years ago.
I know that %d is for int, and %u for unsigned int and %p for the address.
But my question is we can print the address using %u,%d on a Windows machine but the same cannot be done on Linux.
For example:
#include<stdio.h>
int main() {
int x=15;
int *p;
p=&x;
printf("%d \n",x);
printf("%d \n",&x);
printf("%u \n",&x);
printf("%p \n",p);
printf("%x \n",p);
printf("%u \n",&p);
return 0;
}
OUTPUT:
15
2358812
2358812
000000000023FE1C
23fe1c
2358800
It is seen that the hex value(23fe1c) is changed to decimal using %d and %u.
But the exact same code gives error on Unix/Linux.
ERROR:
format (%d) expects arguments of type 'int', but argument 2 has type 'int*'
GCC has the ability to perform type checking on variadic functions, specifically using the format function attribute. This forces a check that the types passed as the variadic arguments exactly match the format string supplied.
GCC complains because the data types used in the printf format string and the passed parameters are not compatible. The portable and standard way to print a pointer is by using the %p specifier. However, you can find other places where people may use %x for the same purpose. As others have said, using %u and %d are not compatible with a pointer data type. They may work on some compilers like in the Windows case but other stricter compiler (like GCC in this case) could complain about the datatype being passed since int is not the same as int*. In order to use the %p notation you have to cast the pointer to void, as from the C99 standard:
p The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.
That's said, the %p is implementation defined so the output could change from an implementation to the other. Any way using %d or %u to print a pointer in general is not a good idea. Depending on the implementation a pointer could be a simple int or a long int. So you could get an undefined behavior if you try to print a pointer by using a %d or %u on a machine where the addresses are stored in long int variables.
If you would like to control the output then another option is to use uintptr_t provided by #include <inttypes.h>.

Getting Warning When Using SizeOf [duplicate]

This question already has answers here:
'%d' expects argument of type 'int', but argument 2 has type 'long unsigned int' [-Wformat=] [duplicate]
(3 answers)
Closed 9 years ago.
I am getting a warning warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat]
I am writing a very basic program which gives the size of the data type but in the Linux environment I am getting this warning whereas in Visual Studio, the program works without any warning. The source code is as below :-
#include<stdio.h>
int main()
{
int a;
printf("\nThe Size Of Integer A Is = \t%d", sizeof(a));
return 0;
}
Answer will be appreciated and also can anyone tell me a proper way of solving such kind of warnings as I am new to this C and it's standard.
sizeof returns size_t type. Use %zu specifier to print the value of sizeof.
printf("\nThe Size Of Integer A Is = \t%zu", sizeof(a));
C11 6.5.3.4 The sizeof and _Alignof operators:
5 The value of the result of both operators is implementation-defined, and its type (an
unsigned integer type) is size_t, defined in <stddef.h> (and other headers).
NOTE: As loreb pointed out in his comment that when you will compile your code in Windows, then most probably you will get the warning like:
[Warning] unknown conversion type character 'z' in format [-Wformat]
[Warning] too many arguments for format [-Wformat-extra-args]
sizeof return size_t and not int
Use %zu in printf
In C99 the correct format for a size_t variable is %zu.
Use:
printf("\nThe Size Of Integer A Is = \t%zu", sizeof(a));

Resources