7

Once I assumed that these two have the same meaning but after reading more about it i'm still not clear about the difference. Doesn't the local scope sometimes refer to scope of function? and what does it mean that only labels have a function scope?

user103214
  • 3,478
  • 6
  • 26
  • 37
  • 10
    what is sometimes called "local scope" and sometimes called "block scope" in C++03 is now called "block scope" everywhere in C++11. One source of confusion less! – Johannes Schaub - litb Oct 28 '11 at 19:32

5 Answers5

17
void doSomething()
{                                    <-------
     {                   <----               | 
                              |              |
         int a;           Local Scope    Function Scope
                              |              |
     }                   <----               | 
}                                    <------- 

Function Scope is between outer { }.

Local scope is between inner { }

Note that, any scope created by {``} can be called as the local scope while the {``} at the beginning of the function body create the Function scope.
So, Sometimes a Local Scope can be same as Function Scope.

what does it mean that only labels have a function scope?

Labels are nothing but identifiers followed by a colon. Labeled statements are used as targets for goto statements. Labels can be used anywhere in the function in which they appear, but cannot be referenced outside the function body. Hence they are said to have Function Scope.

Code Example:

int doSomething(int x, int y, int z)
{
     label:  x += (y + z);   /*  label has function scope*/
     if (x > 1) 
         goto label;
}

int doSomethingMore(int a, int b, int c)
{
     if (a > 1) 
         goto label; /*  illegal jump to undefined label */
}
Alok Save
  • 202,538
  • 53
  • 430
  • 533
5

Local scope is the area between an { and it's closing }. Function scope is the area between the opening { of a function and its closing }, which may contain more "local" scopes. A label is visible in the entirety of the function within which it is defined, e.g.

int f( int a ) 
{
    int b = 8;
    if ( a > 14 )
    {
       int c = 50;
       label:
       return c - a - b;
    }
    if ( a > 7 ) goto label;
    return -99;
}

int c is not visible outside its enclosing block. label is visible outside its enclosing block, but only to function scope.

Rob K
  • 8,757
  • 2
  • 32
  • 36
  • 3
    I had always assumed that labels had global scope. Function scope is much more sane. – deft_code Oct 28 '11 at 19:32
  • If labels had global scope, you could jump from the body of one function to the body of another, which would be crazy. – Rob K Oct 28 '11 at 19:42
  • No, @Rob, you could only jump from one function to another if the language also allowed non-local gotos. They're not necessarily a package deal, though. Local-only gotos with global label names just means you have to be careful when choosing names for your labels so they don't interfere with labels elsewhere in the program, just like when choosing names for preprocessor macros. – Rob Kennedy Oct 28 '11 at 19:55
  • Good clarification. Label names with global scope /really/ wouldn't make any sense without accompanying non-local gotos. As you say, that would just be namespace pollution. – Rob K Oct 28 '11 at 20:37
2

Doesn't the local scope sometimes refer to scope of function?

Yes. In most C-derived languages, variables are valid in the scope in which they're declared. If you declare a variable inside a function, but not within any other code block, then that variable is usually called a "local" or "automatic" variable. You can refer to it anywhere in the function. On the other hand, if you declare your variable inside another code block -- say, in the body of a conditional statement, then the variable is valid only inside that block. Several other answers here give good examples.

and what does it mean that only labels have a function scope?

Context would be helpful, but it means that you can't jump from one function to a label in a different function.

void foo(int a) {
    if (a == 0) goto here;  // okay -- 'here' is inside this function
    printf("a is not zero\n");
    goto there;             // not okay -- 'there' is not inside this function
here:
    return;
}

void bar(int b) {
    if (b == 0) goto there; // okay -- 'there' is in this function
    printf("b is not zero\n");
there:
    return;
}

Not to stir up a hornet's nest, but the scope of labels probably won't come up too often. Labels are mainly useful with the goto statement, which is needed only very rarely if ever, and even if you did choose to use goto you probably wouldn't even think of trying to jump into a different function.

Caleb
  • 124,013
  • 19
  • 183
  • 272
1

The scope of the function is slightly larger than the scope of the function body: The function arguments are in the outer scope, while local variables are only in the inner one. This is most visibly manifest in a function-try-block:

void f(int a) try {
  // function body
} catch(...) {
  // catch block
}

Inside the catch block, only the variables in function scope are still in scope, but not the local variables.

Of course you can and do also introduce further, deeper nested scopes all the time, e.g. in for loop bodies or conditional bodies.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • +1 I've written a lot of C++ in the past, but I've never seen that construct. – Caleb Oct 28 '11 at 19:47
  • @Caleb: You might want to have a look at [this](http://stackoverflow.com/questions/6756931/difference-between-try-catch-syntax-for-function/) – Alok Save Oct 28 '11 at 20:00
  • @Caleb: Imagine using that for a constructor... then forget about ever using this right away :-) – Kerrek SB Oct 28 '11 at 20:51
  • @KerrekSB: It makes me wonder what else I might have missed, but I'm not sure I really want to know. – Caleb Oct 28 '11 at 22:03
1
bool m[3][3];
void f1()
{
  int i;
  // redefining a variable with the same name in the same scope isn't possible
  //int i; //error C2086: 'int i' : redefinition
}

void f2()
{
  int i; // ok, same name as the i in f1(), different function scope.

  {
    int i; // ok, same name as the i above, but different local scope.
  }

  // the scope if the following i is local to the for loop, so it's ok, too.
  for (int i = 0; i < 3; i++)
  {
    for (int j = 0; j < 3; j++)
    {
      if (m[i][j])
        goto loopExit;
    }
  }
loopExit:
  std::cout << "done checking m";
// redefining a label with the same name in the same function isn't possible
// loopExit:; // error C2045: 'loopExit' : label redefined
}

void f3()
{
loopExit:; // ok, same label name as in f2(), but different function scope
}
Andreas Haferburg
  • 5,189
  • 3
  • 37
  • 63