In standard C (without compiler-specific extensions), consider the following code: int main(void) { int a = 10, *j; void *k; j = k = &a; j++; k++; printf("%u %u", j, k); return 0; } Would this program compile successfully, and why?
-
ANo, it will not compile in standard C because pointer arithmetic on a void pointer (k++) is not allowed
-
BYes, it will compile and both j and k will be incremented correctly by the size of int
-
CNo, it will not compile because assigning &a to a void pointer is forbidden in C
-
DYes, it will compile but the behavior of j++ is undefined for int pointers
Answer
Correct Answer: No, it will not compile in standard C because pointer arithmetic on a void pointer (k++) is not allowed
Explanation
Introduction / Context:This question checks understanding of pointer types and pointer arithmetic rules in standard C. While C allows implicit conversion between object pointers and void *, arithmetic on void * itself is not defined by the C standard. Some compilers provide it as an extension, but portable C code must avoid incrementing or decrementing a void pointer directly.
Given Data / Assumptions:
- a is an int variable.
- j is an int * pointer and k is a void * pointer.
- The assignment j = k = &a; converts &a to void * and then to int *.
- The code then performs j++ and k++ and attempts to print both pointers.
- We are considering standard C, not compiler-specific extensions.
Concept / Approach:Standard C allows assigning the address of any object to a void * pointer, and a void * can be converted back to the original pointer type. However, pointer arithmetic (such as p++, p--, p + n, p - n) is only defined on pointers to complete object types, such as int *, char *, or struct mytype *. A void does not have a defined size, so the compiler cannot know how far to advance a void * when performing k++. For this reason, arithmetic on void * is not allowed by the C standard and should result in a compilation error.
Step-by-Step Solution:Step 1: The line j = k = &a; is legal because &a (type int *) can be implicitly converted to void * for k, and assigned back to int * for j.Step 2: The statement j++ is valid because j is an int * pointer, and pointer arithmetic on int * is defined to move by sizeof(int) bytes.Step 3: The statement k++ attempts to perform pointer arithmetic on a void * pointer.Step 4: In standard C, void has no size, so the compiler cannot calculate the correct increment for k++.Step 5: Therefore, a conforming compiler must reject k++ with a compilation error, and the program will not compile successfully under standard C rules.
Verification / Alternative check:If you compile this code with a strictly conforming C compiler, you will typically see an error such as "arithmetic on pointer to void" or "invalid use of void expression". Some compilers (for example, GCC with GNU extensions) may treat void * as if it were char * and allow k++, but this behavior is non-standard and should not be relied upon in portable code.
Why Other Options Are Wrong:Option B is incorrect because the standard does not define arithmetic on void *; any compiler that accepts it is using an extension. Option C is wrong because assigning &a to a void * is allowed; void * is explicitly designed to hold pointers to any data type. Option D is incorrect because j++ on an int * is perfectly well-defined; it moves the pointer by sizeof(int) bytes.
Common Pitfalls:A common mistake is to assume that void * behaves like a generic pointer that supports all operations, including arithmetic. In reality, it is only a generic container for addresses and must be converted to a specific pointer type before doing arithmetic or dereferencing. Another pitfall is relying on compiler extensions; such code may fail to compile or behave differently on other compilers or platforms.
Final Answer:The program will not compile in standard C because pointer arithmetic on a void pointer (k++) is not allowed.