-1

Reading a lot of definition of namespace and scopes cannot understand exactly the difference between the two terms.

For example:

If an identifier designates two different entities in the same name space, the scopes might overlap.

It is really confusing me. Can someone clarify it as simple as possible underlining the difference.

Sabrina
  • 1,460
  • 11
  • 23

2 Answers2

0

You left off the second part of that statement:

If so, the scope of one entity (the inner scope) will end strictly before 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.

Online draft of the C2011 standard, §6.2.1, para 4.

Example:

void foo( void )
{
  int x = 42;
  printf( "x = %d\n", x );       // will print 42

  do
  {
    double x = 3.14;            
    printf( "x = %f\n", x );    // will print 3.14
  } while ( 0 );

  printf( "x = %d\n", x );      // will print 42 again
}

You have used the same identifier x to refer to two different objects in the same namespace1. The scope of the outer x overlaps the scope of the inner x. The scope of the inner x ends strictly before the scope of the outer x.

The inner x "shadows" or "hides" the outer x.


  1. C defines four namespaces - label names (disambiguated by the `goto` keyword and `:`), struct/union/enum tag names (disambiguated by the `struct`, `union`, and `enum` keywords), struct and union member names (disambiguated by the `.` and `->` operators), and everything else (variable names, function names, typedef names enumeration constants, etc.).

John Bode
  • 119,563
  • 19
  • 122
  • 198
0

"Namespace" in C has to do with the kinds of things that are named. Section 6.2.3 of the standard distinguishes four kinds of namespaces

  • one for labels
  • one each for the tags of structures, unions, and enumerations
  • one for the members of each structure or union
  • one for all other identifiers

Thus, for example, a structure tag never collides with a variable name or the name of any structure member:

struct foo {
    int foo;
};
struct foo foo;

The usage of the same identifier, foo, for each of the entities it designates therein is permitted and usable because structure tags, structure members, and ordinary variable names all belong to different name spaces. The language supports this by disambiguating the uses of identifiers via language syntax.

"Scope", on the other hand, has to do with where -- in terms of the program source -- a given identifier is usable, and what entity it designates at that point. As section 6.2.1 of the standard puts it:

For each different entity that an identifier designates, the identifier is visible (i.e., can be used) only within a region of program text called its scope. Different entities designated by the same identifier either have different scopes, or are in different name spaces.

Identifiers belonging to the same namespace may have overlapping scope (subject to other requirements). The quotation in your question is an excerpt from paragraph 4 of section 6.2.1; it might help you to read it in context. As an example, however, consider

int bar;
void baz() {
    int bar;
    // ...
}

The bar outside the function has file scope, starting immediately after its declaration and continuing to the end of the enclosing translation unit. The one inside the function designates a separate, local variable; it has block scope, starting at the end of its declaration and ending at the closing brace of the innermost enclosing block. Within that block, the identifier bar designates the local variable, not the file-scoped one; the file-scoped bar is not directly accessible there.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • Is there any way to access outside `bar` inside the `baz()`? – Ravi Raj Jul 15 '20 at 13:08
  • In fact there is, @RaviRaj. In the first place, you can do that freely previous to the declaration of the local `bar`. After the declaration of the local `bar`, you need a nested block in which you declare `extern int bar`. Within that block, `bar` should refer to the file-scope variable. But do not do either one of those, because both are confusing and error-prone. If you want to access the file-scope `bar` then the best practice is to avoid shadowing it in the first place. – John Bollinger Jul 15 '20 at 15:38