So, I am practicing pointers in detail. I just studied that if we perform operations like -
int a = 1025;
int *ptr = &a;
printf("The size of integer is = %d\n", sizeof(int));
printf("The address = %d, value = %d\n", ptr, *ptr);
printf("The address = %d, value = %d\n", ptr+1, *(ptr+1));
char *pointer;
pointer = ptr;
printf("The size of character is = %d\n", sizeof(char));
printf("The address = %d, value = %d\n", pointer, *pointer);
printf("The address = %d, value = %d\n", pointer+1, *(pointer+1));
This should throw an error in pointer = ptr;
because they have a different type, and the way to make this work is by typcasting int *ptr
to (char*)ptr
.
But somehow, this is working without type casting and here is the output-
The size of integer is = 4
The address = 15647756, value = 1025
The address = 15647760, value = 15647756
The size of character is = 1
The address = 15647756, value = 1
The address = 15647757, value = 4
Why is this working, and not showing an error?
Also, we know that Void Pointers cannot be incremented, like we cannot do void pointer + 1
but when I run this-
int a = 1025;
int *ptr = &a;
printf("The address = %d, value = %d\n", ptr, *ptr);
void *ptr1;
ptr1 = ptr;
printf("%d\n", ptr1+1);
It returns -
The address = 15647756, value = 1025
15647757
Clearly, the void pointer is getting incremented, which should NOT happen, Please explain this as well?
I am using gcc 9.4.0 version compiler on an 20.04 LTS ubuntu machine.
This should throw an error in
pointer = ptr;
because they have a different type, and the way to make this work is by typcastingint *ptr
to(char*)ptr
.
You are correct inasmuch as C does not define behavior for assignment of a value of type int *
to an object of type char *
. This is because int *
and char *
are not "compatible" types, and neither is void *
.
Even interpreting "error" generously, however, there are few situations about which it is correct to say that a C implementation "should throw an error". These are the constraint violations, which C requires conforming implementations to diagnose. And that's all C requires in those situations. It does not require the implementation to reject the offending program, so if that's part of what "error" means to you then no, the C language specification provides no basis for saying that any particular code should throw an error.
Additionally, compilers do not necessarily diagnose all constraint violations by default. GCC is one that does not, but its -pedantic
option option requests that it emit all the diagnostics that the language standard requires of conforming implementations (among other things related to conformance to the standard). Or if you want GCC not only to diagnose but also to reject all code containing constraint violations then use -pedantic-errors
instead.
By default, GCC is happy to accept that assignment, and will interpret it as if the needed cast had been provided. This is an extension to standard C.
Also, we know that Void Pointers cannot be incremented, like we cannot do
void pointer + 1
No. We know that the C language spec does not define behavior for arithmetic with void pointers. That's not the same thing. GCC, as another extension, does define such behavior, as equivalent to arithmetic on a char *
.
Relying on extensions such as these makes your programs less portable, but undefined behavior is undefined. You cannot rely on the compiler to reject such programs.