3

In the following code, 2 is printed.

int x = 1;
int f(int y)
{
    return x;
}

int main() {
    x = 2;
    printf("%d", f(0));
}

How is it happening if we have static scoping in C? Why isn't 1 printed?

Printing 2 in this case isn't a dynamic scoping, is it?

I thought that in static scoping it should take the nearest x to the function definition.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
RoG
  • 411
  • 4
  • 20
  • 4
    You only declare a single `x` here (as a global variable). So any modification done from anywhere in the code will affect any later use from any other place of the code. – NiBZ Jan 24 '17 at 13:21
  • 1
    Why would it? x is _not constant_ and is modified before it's returned. – George Jan 24 '17 at 13:22
  • It is taking the closest one (there's only one to choose from though) and the assignment happens before the function call so ofc it prints 2. Works as intended (TM). – Borgleader Jan 24 '17 at 13:22
  • Those are usually called dynamic and *lexical* scoping. – molbdnilo Jan 24 '17 at 13:35
  • Because C and C++ (and almost every other programming language) execute code from the top to the bottom? – Lundin Jan 24 '17 at 13:35

4 Answers4

9

It does take the nearest x, but since you only have one x it doesn't really matter.

If you change the code to

int x = 1;
int f(int y)
  {
    return x ;
  }

int main() {
    int x=2;       
    printf("%d", f(0));
}

so you have 2 x, the global one and the local one in main you will see 1 getting printed.

nwp
  • 9,623
  • 5
  • 38
  • 68
  • Why So , I am unable to understand. – Suraj Jain Jan 24 '17 at 13:58
  • @SurajJain Can you be more specific? – nwp Jan 24 '17 at 14:15
  • I Mean why are we not able to print that value. , i do not understand your answer. – Suraj Jain Jan 24 '17 at 15:54
  • @SurajJain By "that value" you mean the local `int x=2;` inside `main`? Because the `x` in `f` looks up the "nearest" `x` which is the global one. The lookup is done at compile time by only looking at `f` and upwards without checking at runtime where `f` was called from because that would be slow and confusing. – nwp Jan 24 '17 at 16:01
  • I mean why is the value 2 is printing , it should print 1 right because f(0) should return 1. – Suraj Jain Jan 24 '17 at 17:04
  • @SurajJain In my code the value `1` is printed because we print the global `x` which has the value `1`, but in the original code `2` is printed because the global `x` was overwritten with `x=2;` before it was printed. Are you confused because I wrote "2 `x`" in my answer? – nwp Jan 24 '17 at 17:13
  • How could it be overwritten ? – Suraj Jain Jan 24 '17 at 19:38
  • @SurajJain You start with `int x = 1;` and `x` is `1`. Then you do `x = 2;` and now `x` is `2`. I'm not sure what you are asking. We can [discuss this in chat](https://chat.stackoverflow.com/rooms/116940/c-questions-and-answers) if you want. – nwp Jan 24 '17 at 19:55
  • ANd main thing that i find faulty with your code is that you declare another `int x` in main so how can it overwrite the global x, i find this problematic. – Suraj Jain Jan 25 '17 at 12:28
  • ok so you mean global was over written in original code , why so ? – Suraj Jain Jan 25 '17 at 12:29
3

Those are usually called dynamic and lexical scoping.

Lexical scoping is determined entirely at compile time, dynamic scoping at runtime.

You only have one variable named "x", so scope is irrelevant to your program.

Here's a program that would be different depending on the scoping rules:

int x = 0;

int f()
{
    return x;
}

int main()
{
    int x = 1;
    printf("%d\n", f(x));
}

Under lexical scoping, f returns the value of the x that is lexically "nearest" - the global one.
So it would print 0;

Under dynamic scoping, f would return the value of the newest x, which is the one in main.
So it would print 1.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
2

The scoping is moot here since you have not declared an x locally that would have otherwise shadowed the global x.

2 is printed.

x is assigned in main to 2 immediately before f is called with the parameter 0.

(Conceptually int x = 1; is ran before main is entered.)

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
1

It is the way the compiler generates the assembly/machine code.

  • first global variable X is stored in memory location "abc"
  • next main is executed: global variable X at "abc" is changed to 2
  • Now function f() is called:
    • function f returns the value of global variable X at "abc": being 2
  • the return value of f() is printed.

So if you wanted a different X in the main-function scope, you should have made a new object, like in the answer by nwp.

JHBonarius
  • 10,824
  • 3
  • 22
  • 41
  • 1
    "you should have made a new object, like in the answer by nwp." That's not what happens in @nwp 's code, less you're using the worlds worst compiler. – George Jan 24 '17 at 13:33
  • @george: true, but seeing the simplicity of the questions, I did not want to elaborate on compiler details ;) – JHBonarius Jan 24 '17 at 14:02
  • I kind of got the impression from the last line that something like `printf("%d", f(x));` would print 2 <-- obviously you can't initialize a variable twice, so it might be a good idea to just clarify that a little? Up to you, you can still have my vote :) – George Jan 24 '17 at 14:08