13

I have been reading the C++ primer 5th edition. In the third paragraph of Function Parameter List of Chapter 6.1 . It writes "Moreover, local variables at the outermost scope of the function may not use the same name as any parameter". What does it mean?

I am not native English speaker. I don't understand the actual meanings of "outermost scope" of the function.

Spikatrix
  • 20,225
  • 7
  • 37
  • 83
LiuHao
  • 412
  • 1
  • 6
  • 16

5 Answers5

24

The outermost scope of the function is the block that defines the function's body. You can put other (inner) blocks inside that, and declare variables in those which are local to that block. Variables in inner blocks can have the same name as those in an outer block, or the function parameters; they hide the names in the outer scope. Variables in the outer block can't have the same name as a function parameter.

To demonstrate:

void f(int a)           // function has a parameter
{                       // beginning of function scope
    int b;              // OK: local variable
    {                   // beginning of inner block
        int a;          // OK: hides parameter
        int b;          // OK: hides outer variable
    }                   // end of inner block
    int a;              // Error: can't have same name as parameter
}
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • 7
    I'd just suggest avoiding using block and scope interchangeably. The "beginning of inner block" comment, while correct, omits the succint detail that this block introduces a new inner _scope_. That "The outermost scope of the function is the block that defines the function's body" is not really true, rather, the block that defines the functions body also defines its outermost scope. A scope is not a block, it is defined by one. – davmac May 08 '15 at 14:11
  • 2
    @davmac: Thanks for the grammatical critique. I think the wording is clear enough as it is. – Mike Seymour May 08 '15 at 14:23
  • 4
    @MikeSeymour the critique is more technical than grammatical, but hey, it's your answer. – davmac May 08 '15 at 14:31
15

It means you can't do things like this:

void foo (int x)
{
    int x = 4; //in the outermost scope, invalid
}

You can, however, do this:

void foo (int x)
{
    { //this introduces a new scope
        int x = 4; //not in the outermost scope, valid
    }
}
TartanLlama
  • 63,752
  • 13
  • 157
  • 193
  • 5
    @dwcanillas not in such a simplified example, but in a more complex example where the scopes are introduced by loops or `if` statements, I'm sure you could find a reasonable case. It's generally a good idea to avoid "overloading" names though. – TartanLlama May 08 '15 at 14:09
  • 3
    If you feel like this is a good idea, your function is probably too long or too complex. – Baum mit Augen May 08 '15 at 14:20
7

It means that this is invalid:

void f(int p)
{
   int p = 3;
}

wheras this

void f(int p)
{
  {
    int p = 3;
  }
}

is allowed.

martin
  • 3,149
  • 1
  • 24
  • 35
4

This rule is valid not only for function parameters of function definitions but also for iteration and conditional statements and for exceptions handlers

3.3.3 Block scope

2 The potential scope of a function parameter name (including one appearing in a lambda-declarator) or of a function-local predefined variable in a function definition (8.4) begins at its point of declaration. If the function has a function-try-block the potential scope of a parameter or of a function-local predefined variable ends at the end of the last associated handler, otherwise it ends at the end of the outermost block of the function definition. A parameter name shall not be redeclared in the outermost block of the function definition nor in the outermost block of any handler associated with a function-try-block.

3 The name declared in an exception-declaration is local to the handler and shall not be redeclared in the outermost block of the handler.

4 Names declared in the for-init-statement, the for-range-declaration, and in the condition of if, while, for, and switch statements are local to the if, while, for, or switch statement (including the controlled statement), and shall not be redeclared in a subsequent condition of that statement nor in the outermost block (or, for the if statement, any of the outermost blocks) of the controlled statement; see 6.4.

For example this code snippet is invalid

if( int x = SomeFunction() )
{
    int x; // invalid declaration
    //...
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

Imagine that you have a function 'foo' that takes an integer parameter 'bar'.

int foo (int bar)
{
    int bar = 0; // < illegal, this is the 'outermost' scope
    if (bar == 10) {
        int bar = 5; // legal (though unadvisable) this 'shadows' the passed-in 'bar'
        return bar;
    }
    return bar;
}

The first internal declaration of 'bar' is illegal, since the passed in parameter is also declared in the same context (even though the syntax doesn't necessarily make that clear.)

Just as it would be incorrect to write:

int bar;
char bar[10];

Since those two variables share the same scope.

The second declaration of bar (in the function foo above) is legal (though usually a bad idea) since it is declared in the inner scope of the 'if' and therefore fair game.

Hope that helps.

Lee K-A
  • 743
  • 6
  • 4