Reputation: 171
I'm currently learning about pointers and the concept of pass-by-value, and I have this C code block:
void doSomething(int b){
b = 6;
printf("%d", b);
}
int a = 5;
int main(void){
doSomething(a);
printf("%d",a);
return 0;
}
I should get the output 65
with no errors on compilation nor on execution. By tracing the code, here is how I'm seeing it:
a
is assigned the value 5
.doSomething(a) == doSomething(5)
.Now prior to running the line b = 6;
, I'm fairly certain that b == 5
. So by running the line, the program is effectively reading:
5 = 6;
A constant (for a lack of a better term on my part) is being assigned to another constant. In Python this would have failed with a syntax error, and it makes sense to have an error. Why doesn't it raise a syntax error?
Upvotes: 0
Views: 74
Reputation: 222856
Here is how the C 2018 standard says function calls are executed, in 6.5.2.2 4:
In preparing for the call to a function, the arguments are evaluated, and each parameter is assigned the value of the corresponding argument…
What this means is that, in the function definition with void doSomething(int b)
, b
is defined to be a variable (technically an object) on its own, and, when the function is called with doSomething(a)
or doSomething(5)
, the value of a
or 5
is assigned to b
, as if you did b = a
or b = 5
. It is just an assignment; it does not create any enduring connection between b
and a
or 5
.
Inside the function, b
is a variable, so of course you can execute the assignment b = 6
. This simply assigns 6
to the variable b
.
Here is more about how parameters are their own variables. 3.16 defines parameter as:
… object declared as part of a function declaration or definition that acquires a value on entry to the function,…
6.9.1 9 says:
Each parameter has automatic storage duration; its identifier is an lvalue…
Upvotes: 1
Reputation: 1738
5 = 6;
is not same as b = 6;
b = 6;
assigns value 6 to variable b
, b
has automatic storage that's a different story
5 = 6;
is not a valid expression in C
, you have misunderstood the concept thinking both are same.
Run the below program to see an error:
void doSomething(int b){
b = 6;
5 = 6;
printf("%d", b);
}
int a = 5;
int main(void){
doSomething(a);
printf("%d",a);
return 0;
}
Now you will get error for the 3rd line:
error: lvalue required as left operand of assignment
5 = 6;
refer lvalues and rvalues
Upvotes: 1
Reputation: 171
I decided to just put 5 = 6;
in main()
. It yielded a compilation error similar to the one in Python and Johnny Mopp's and Martin James's comments now make sense.
b
is indeed a variable and not an actual constant. I was under the impression that pass-by-value was to only pass what the variable contained and exactly that, and disregarded the idea that b
was a variable, thinking that the function only allowed integers and that b
was not anything but a placeholder, different from a variable.
I was under the impression that b
was exactly 5
, and not a variable assigned the value 5
.
What I am currently seeing in my head is this:
a
is assigned the value 5
.doSomething(a) == doSomething(5)
.b
is assigned the value 5
on invocation of doSomething(5)
.b
is assigned the value 6
as per the line b = 6;
.Thank you everyone for the comments and answers!
Upvotes: 1
Reputation: 211610
If you look in your debugger you're going to see that there's two variables in play here, the a
which is, in your code, global in scope, and b
, which is local to the doSomething()
function.
These are two completely independent variables. When you call the doSomething()
function, imagine the following happens:
stack_push(a);
call(doSomething);
Where inside of doSomething()
the compiler does something like:
int b = stack_pop();
...
That's how a "copy" is made.
Note that this model for thinking about variables is an approximation and an optimizing compiler may do something completely different so long as the same result is achieved, as per the C spec.
Upvotes: 1