I'm learning C from Robert C. Seacord's "Effective C" book, and there's an introduction to pointers and call-by-value vs. call-by-reference by writing a function that swaps the values of variables (called swap
). The end result is:
#include <stdio.h>
void swap(int *pa, int *pb) {
int t = *pa;
*pa = *pb;
*pb = t;
}
int main(void) {
int a = 21;
int b = 17;
swap(&a, &b);
printf("a = %d, b = %d\n", a, b);
return 0;
}
This is all well and clearly explained but after I read this part,
*pa = *pb;
This dereferences the pointer
pb
, reads the referenced value, dereferences the pointerpa
, and then overwrites the value at the location referenced bypa
with the value referenced bypb
.
I started thinking: would it be possible to make variable a
point to the memory range holding the value pointed to by variable b
(and vice versa) instead of overwriting the memory ranges of a
and b
?
At least, based on little what I know, "in C, variables are human-readable names for the computer's memory addresses used by a running program". I understand that this is a contrived example (found also in many other tutorials as well) but still wondering whether the overwriting of address ranges is wasteful/inefficient.
Tried to google this but kept getting irrelevant results; probably because I wasn't using the right terms... I would probably find the answer in a couple of weeks, but had to put this in writing as it was constantly gnawing at me. Thank you!
CodePudding user response:
No, it is not possible. a
and b
are compile-time names for memory regions. You can't turn a memory region into a different memory region.
After you compile the code, it looks more like this:
int main(void) {
allocate_local_variables(8);
*(int*)(local_variables 0) = 21;
*(int*)(local_variables 4) = 17;
swap(local_variables 0, local_variables 4);
printf("a = %d, b = %d\n", *(int*)(local_variables 0), *(int*)(local_variables 4));
return 0;
}
and your question is: "Can I make it so local_variables 0
points to local_variables 4
?" which is clearly nonsensical.
Perhaps there is a way to make the compiler start writing local_variables 4
instead of local_variables 0
when the program says a
, but I don't think there is one. Even if there is, it wouldn't do what a swap function is supposed to do, since the compiler would only be doing this within a certain section of code. If it worked this way, you couldn't do if(random_number() < 5) swap(&a, &b);
because the compiler wouldn't know whether to swap them or not!
CodePudding user response:
The declarations int a = 21;
and int b = 17;
define the symbols a
and b
. In the C computing model, they cause memory to be reserved to represent int
values and they make a
and b
names for that memory (and more than just the memory, also the semantics that come with the object that is created by the definition, including its type).
This binding of the name to the designated memory is an intrinsic part of a definition in C, for definitions of identifiers of objects. The C standard does not provide any mechanism by which the name a
can be changed to refer to the memory allocated for b
or vice-versa.