tags:

views:

336

answers:

6

Which determines the scope of a variable, the declaration or definition?

A: 

The definition determines the scope.

Jerry Coffin
+1  A: 

It enters scope at the ... declarator of the definition. so

int x=3;
{
  int x=x; // x is initialized to itself, uninitialized.
}

The iso c++ spec is unfortunately not freely available, so I can't quote chapter and verse.

Chris Becke
+4  A: 

Declaration. You can declare something external, and it's visible in that file, no matter where it was defined. Similarly, a function is visible anywhere it's declared.

Other than externs and functions though, I can't think of a way to declare a variable that doesn't also define it...

EDIT: OTOH, static (global) variables, the scope is determined by the definition, which is ALSO the declaration.

EDIT 2: Basically I think my point is that you can't really have a definition that isn't ALSO a declaration. so, the only interesting cases are where the declaration isn't also a definition, and that's basically extern with a global in another file, and function declarations...

Brian Postow
Good point that most declarations are also definitions.
Michael Burr
In C++, using declarations are another way to declare something that doesn't define it.
Johannes Schaub - litb
@litb - I was sure there would be something C++ that I was forgetting about. Even though they're not obscure, using declarations aren't exactly everyday things (at least for me).
Michael Burr
using doesn't really separate the decl and defn, it more changes where the scope is... like making the { } not continious or something... but yeah, it does do wacky things to scope.
Brian Postow
This is what i like in C, actually :) Things are clearly defined and you can answer such a question by quoting one paragraph of the standard. In C++, these things are weird and even the Standard's notion of scope is in error ( http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#554 ). One time it's a name that has scope, another time it's the object/variable that has a scope and temporaries suddenly are "local objects" without having defined this term anywhere.
Johannes Schaub - litb
Another non-definition declaration would be a class (forward) declaration.
MSalters
@MSalters yeah, I would say that that's equivalent (But different) to function prototypes...
Brian Postow
Yeah and those aren't variables. Actually, only named objects are variables. Functions and types aren't.
Johannes Schaub - litb
@litb: Yes, I was expanding the answer a bit. In the context of the original question, only extern is really relevant.
Brian Postow
A: 

The documentation that I read says that the declaration determines the scope, but my own test said the contrary:

I get "undefined reference to i" error with the linker:

#include <iostream> // Stream declarations
using namespace std;
    extern int i; //declaration
int prueba();

int main() {
    int i; //Definition
    i=6;
    prueba();
} ///:~

int prueba(){
     cout << i; //cannot access to the scope of i;
}
Haltz
you never actually DEFINE an extern i... the i in main isn't the extern i. if you had another file, with a global int i, then it would print out THAT i.
Brian Postow
Oh thanks!. That has sense.Then the declaration determines the scope and because the first i is global the i in the main is another variable.
Haltz
The point is that declaration and definition are always in the same scope for the same variable, so there's no point in asking which one defines scope. They both do.
Pavel Minaev
@Pavel: Except when they don't like in extern... bet yeah, that's what I said above...
Brian Postow
+2  A: 

Both determine the scope - it's just that they determine the scope of subtly different things.

The definition of an object in C/C++ determines at which scope the actual object is visible in and determines the 'largest scope' of visibility for an object or function.

The declaration determines at which scope a particular 'instance' of the name is visible in.

For example, a global variable is defined at global scope (of course) and is potentially visible at global scope or a tighter scope. But the following declaration of the global variable, g_var, is only visible within function foo():

void foo(void)
{
    extern int g_var;    // the variable g_var has global scope, but this
                         //    declaration has function-level scope

    printf( "g_var is: %d\n", g_var);
}

Brian Postow's point that this distinction really only applies to global variables and functions is a a good one to keep in mind.

Michael Burr
A: 

From the online version of the C standard:

6.1.2.3 A label name is the only kind of identifier that has function scope. It can be used (in a goto statement) anywhere in the function in which it appears, and is declared implicitly by its syntactic appearance (followed by a : and a statement).

6.2.1.4 Every other identifier has scope determined by the placement of its declaration (in a declarator or type specifier). If the declarator or type specifier that declares the identifier appears outside of any block or list of parameters, the identifier has file scope, which terminates at the end of the translation unit. If the declarator or type specifier that declares the identifier appears inside a block or within the list of parameter declarations in a function definition, the identifier has block scope, which terminates at the end of the associated block. If the declarator or type specifier that declares the identifier appears within the list of parameter declarations in a function prototype (not part of a function definition), the identifier has function prototype scope, which terminates at the end of the function declarator. If an identifier designates two different entities in the same name space, the scopes might overlap. If so, the scope of one entity (the inner scope) will be a strict subset of the scope of the other entity (the outer scope). Within the inner scope, the identifier designates the entity declared in the inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope.

Emphasis mine.

John Bode