corvelk
corvelk

Reputation: 171

A constant being assigned to another constant without errors

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:

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

Answers (4)

Eric Postpischil
Eric Postpischil

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

IrAM
IrAM

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

corvelk
corvelk

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:

  • Integer a is assigned the value 5.
  • Since C is strictly pass-by-value, 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;.
  • ...so on and so forth.

Thank you everyone for the comments and answers!

Upvotes: 1

tadman
tadman

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

Related Questions