Calling functions above their declaration

void foo() { bar(); // error: 'bar' has not been declared } void bar() { } namespace N { void foo() { N::bar(); // error: 'bar' is not a member of 'N' } void bar() { } } class C { static void foo() { C::bar(); // works just fine } static void bar() { } }; 

What is the rationale for this inconsistency in handling function calls above their declaration? Why can I do this inside a class, but not inside a namespace or in a global scope?

+6
source share
5 answers

You can define member functions either inside the class, or after the class declaration, or some of them.

To get some consistency here, the rules for a class with functions defined in a string are that it should still be compiled as if functions were defined after the class.

Your code

 class C { static void foo() { C::bar(); // works just fine } static void bar() { } }; 

compiles the same way

 class C { static void foo(); static void bar(); }; void C::foo() { C::bar(); } void C::bar() { } 

and now there is no magic in visibility because functions can be seen by everything declared in the class.

+3
source
  • Namespaces can be reopened, and new things can be added anywhere. Classes cannot be reopened - all their contents must be placed in one place.

  • Function prototypes are legal in namespaces, but not in classes.

You can write

 namespace n { void foo(); void bar() { foo(); } void foo() { } } 

But not

 class C { void foo(); void bar() { foo(); } void foo() { } } 

So classes need such a function much more, and it is much easier for them to implement it for them than for namespaces.

+1
source

Perhaps because you have a class declaration in one place, and the compiler can easily get information about it.

A namespace, on the other hand, can contain it in tons of different files, and you cannot expect the compiler to look through them because it does not know where to look first.

To avoid this, simply use function prototypes .

0
source

I'm not sure, but I think a class is a somewhat object (poorly used), where all its internal components work together (generally speaking), its member definitely needs its methods.

But the namespace is different, the functions are not related. This means that the function is not designed to work with any other functions inside the namespace.

Thus, declarations and definitions of separation are the best you could do.

If foo() needs bar() , it will most likely be in the same declaration file and work this way

0
source

See the quote below from Standard

3.3.7. Scope class [basic.scope.class]

1) The following rules describe the scope of names declared in classes. 1) The potential scope of the name declared in the class consists not only of the declarative region following the name of the declaration, but also of all function bodies, default arguments and brace-or-equalinitializers of non-static data in this class (including such things in nested classes )

2) The name N used in class S must refer to the same declaration in its context and when reassessed in the filled area S. Diagnosis is not required to violate this rule.

 typedef int c; enum { i = 1 }; class X { char v[i]; // error: i refers to ::i // but when reevaluated is X::i int f() { return sizeof(c); } // OK: X::c char c; enum { i = 2 }; }; 
0
source

Source: https://habr.com/ru/post/922205/


All Articles