C++ : what is :: for? - c++

If you go to the accepted answer of this post
Could someone please elaborate on why he uses:
double temp = ::atof(num.c_str());
and not simply
double temp = atof(num.c_str());
Also, is it considered a good practice to use that syntax when you use "pure" global functions?

It says use the global version, not one declared in local scope. So if someone's declared an atof in your class, this'll be sure to use the global one.
Have a look at Wikipedia on this subject:
#include <iostream>
using namespace std;
int n = 12; // A global variable
int main() {
int n = 13; // A local variable
cout << ::n << endl; // Print the global variable: 12
cout << n << endl; // Print the local variable: 13
}

:: is the scope resolution operator. Its use in this scenario, as a unary operator, is to ensure that the name (atof) is always looked up in the global scope -- this can be useful to prevent name hiding from interfering with the lookup.

The :: operator is scope resolution operator.
when used with class specifier as like A::a, it is to access the data memeber a of the class A.
when used without any specifier, it access the global variable.
It is used mainly in the following contests.
To refer to the global variables.
To refer to the static members of the class
To avoid ambiguites, when a class inherits from multiple [ non-virtual
base ] classes.
With using directive, to use the base class functions in the derived class, when there is a function in base class with name same as that of the derived class, but for a different type.
To access the functions defined in the global scope, when you have a function defined with the same signature, as in double temp = ::atof(num.c_str());
To create objects of the nested classes.

Lets say you have two versions of a function f() one defined outside a namespace and one defined inside. Now lets say you have one more function g() in the same namespace. Now if you do f() inside g() it will call the one defined in the same namespace. But if you want to call the global version you need to do ::f()

::func() means that this function is not affiliated with any specific class. It is used when there exist many functions with the same name, and to avoid confusion between the one you want and specific member functions you precede the function name with the scope operator.
From C++ Primer, 4th edition, section 17.2.1:
"Names defined at global scope - names declared outside any class, function, or namespace - are defined inside the global namespace. The global namespace is implicitly declared and exists in every program. Each file that defines entities at global scope adds those names to the global namespace.
The scope operator can be used to refer to members of the global namespace. Because the global namespace is implicit, it does not have a name; the notation
::member_name
refers to a member of the global namespace."

Related

Member's potential scope for struct vs namespace

Referring to this code:
namespace Y {
char f() { return y; } // error: y was not declared in this scope
char y;
}
struct X {
char f() { return x; } // OK
char x;
};
As per basic.scope.namespace#1:
The declarative region of a namespace-definition is its
namespace-body. Entities declared in a namespace-body are said to be
members of the namespace, and names introduced by these declarations
into the declarative region of the namespace are said to be member
names of the namespace. Its potential scope includes its namespace from the name's point of declaration onwards.
QUESTIONS
Is it correct to say that the error was due to the fact that Y::y is not yet declared in Y::f()?
I can't figure why there isn't a "reodering" for namespace members during declaration while for struct there is. What could be the reason for disallowing such behavior? Does the standard says something similar?
Is it correct to say that the error was due to the fact that Y::y is not yet declared in Y::f()?
Yes.
I can't figure why there isn't a "reodering" for namespace members during declaration while for struct there is. What could be the reason for disallowing such behavior? Does the standard says something similar?
The biggest hindrance for namespaces as opposed to classes, is that they are never "closed". You can always add members to a namespace by re-opening it in another translation unit and declaring more stuff in it. A class declaration however, for all its members, must appear entirely in a single translation unit. And there is no adding to it later.
[class.mem]/1
The member-specification in a class definition declares the full set
of members of the class; no member can be added elsewhere.
The problem for namespaces is intractable. But classes only require a little more, quite localized, work.
It is therefore much easier, both to a language designer and a compiler writer, to demand namespace declarations appear before they are used.
You should also note that you can only use other members of the class in only a specific set of places inside the definition.
[class.mem]/6
A class is considered a completely-defined object type ([basic.types])
(or complete type) at the closing } of the class-specifier. Within the
class member-specification, the class is regarded as complete within
function bodies, default arguments, noexcept-specifiers, and default
member initializers (including such things in nested classes).
Otherwise it is regarded as incomplete within its own class
member-specification.
You are mistaken thinking that for structures there is "reordering".
Consider the following structure definition.
#include <iostream>
struct A
{
char s[N];
enum { N = 10 };
};
int main()
{
return 0;
}
The compiler will issue an error because the name N is not yet declared when it is used in the array declaration. So neither "reordering" exists in the class scope. As for member functions then names used within a member function are at first searched in the class scope.
Moreover a name declared in a namespace can hide the same name declared in the outer namespace. As result the "reordering" breaks scopes of variables.

The meaning of the name used in the scope word combinantion

I don't understand sense of the name used in.... What does it mean? For example (3.4.1/7):
A name used in the definition of a class X outside of a member
function body...
Consider the following example:
class A { static const int a = 4; }
int b = A::a;
The name a after the nested-name-specifier used into the global scope or it used into the class scope?
The namespace analog is defined pretty clear in the 7.3.1/6:
The enclosing namespaces of a declaration are those namespaces in
which the declaration lexically appears, except for a redeclaration of
a namespace member outside its original namespace (e.g., a definition
as specified in 7.3.1.2).
Disclaimer: Warning, language-laywer answer.
What is a "scope"?
Generally, I'd say that a scope is understood as the part of the program text enclosed by {} other than the initializer-brackets. TC++PLv4 p157 "A declaration introduces a name into a scope".
Declarative region
In [basic.scope.declarative]/1, we find the definition of a declarative region:
Every name is introduced in some portion of program text called a declarative region, which is the largest part of the program in which that name is valid, that is, in which that name may be used as an unqualified name to refer to the same entity.
I think we can see the part after "that is" as a definition of the validity of a name.
Scope
[basic.scope.declarative]/1 continues with the definition of scope:
In general, each particular name is valid only within some possibly discontiguous
portion of program text called its scope.
This only defines what the scope of a name is. In the phrases "used in global scope" or "used in the scope of the class", the term scope is used not related to a specific name. Similarly, [basic.scope.declarative]/3
The names declared by a declaration are introduced into the scope in which the declaration occurs, except [...].
Here, the term scope is also used in that second meaning, unrelated to a specific name.
Defining the second meaning of "scope"
Several language features such as block statements, namespaces and classes introduce a new scope. E.g. [stmt.block]/1
A compound statement defines a block scope.
Scope in its second meaning is used at least in three different contexts:
looked up in the scope of X
used in the scope of X
is in the scope of X
Looked up in the scope of X
Example: 3.4.3/1
If the nested-name-specifier of a qualified-id nominates a class, the name specified after the nested-name-specifier is looked up in the scope of the class, except for the cases listed below.
class X
{
int m;
void foo() { int n; }
};
decltype(X::m) v; // legal
decltype(X::n) w; // illegal
In this context, the scope of class X does not extend to any nested scopes such as member functions or nested classes.
Used in the scope of X
Example: 3.3.7/2
The name of a class member shall only be used as follows:
in the scope of its class (as described above) or a class derived from its class,
[...]
class X
{
int m;
void foo()
{
decltype(m) n;
}
static int o;
};
int X::o = decltype(m)();
Here, the scope of class X extends to nested scopes and other parts of the program, such as definitions of members outside of the class body.
Note that the initializers of static data members, nested classes and local classes are explicitly defined to be in the scope of wherever the static data member / class has been declared. For member functions, I can only find non-normative notes such as 9.3/5
The member function f of class X is defined in global scope; the notation X::f specifies that the function f is a member of class X and in the scope of class X.
As I understand it, this "is in the scope of" for member functions and nested/local classes says that those newly introduced scopes are nested scopes.
"Used in the scope of X" does not occur very often in the Standard. One could argue that 3.3.7/2 should be extended to nested scopes, to make "used in the scope of" consistent with "looked up in the scope of".
To be in the scope of X
Example: 8.5/13
An initializer for a static member is in the scope of the member's class.
class X
{
static int m;
static int n;
};
int n;
int o;
int X::m = n; // X::n
int X::n = o; // ::o
Name lookup for unqualified names searches the scopes (plural) "in the order listed in each of the respective categories" [basic.lookup.unqual]/1. For the initializers of the two static data members, the scope of class X is searched first, then any base classes, then the enclosing scope (here: the global scope), [basic.lookup.unqual]/7.
What is meant with "to be in the scope of X" seems to me that for unqualified lookup, the scopes searched are the ones that are searched for names used inside X, maybe plus access rules (initializers of static data members may access private members etc). As said above, this effectively nests scope of member functions and nested classes defined outside their enclosing class' body in the scope of that enclosing class.
Trying to define the scope of X
Not including the weird extensions of "used in the scope of X".
3.3.3 to 3.3.9 categorize various kinds of scopes of names. We can use these categories to categorize the parts of our program where names can be declared: A part of a program where names with block scope can be declared is a block scope. A part of the program where names with class scope can be declared is a class scope. We still need to differentiate different scopes of the same kind:
void foo()
{ // begin scope A
int a; //
{ // begin scope B
int b; //
int c; //
} // end scope B
int d; //
} // end scope A
The Standard calls A an outer scope of B (in name lookup). However, the scope B is not part of the scope A. Maybe something like "B is in the scope of A, but the names declared inside B are not in the scope of A". Consider:
class A
{
int m;
class B
{
int n;
};
};
Here, name lookup "in the scope of the class A" won't find members of the nested class B with unqualified lookup. Also relevant: anonymous unions.
I think the best way to perform this separation is to look at the individual language features which can introduce a scope. For example, [stmt.block]/1 "A compound statement defines a block scope." We can then look at any part X of the program, find the closest previous language feature that introduced a scope which has not ended yet(*), take all the regions of the program where newly declared names are in the same scope (**), and call this the enclosing scope of X.
(*) not ended yet: for a block, the end of the block etc. (i.e., as specified by the language feature) Alternatively, not ended yet = where a name could have been declared that is still valid
(**) in the same scope: searching, beginning from this new declaration, the closest previous language feature that introduced a scope which has not ended yet, shall find the same part of the program
This seems to comply with what has been intended as the definition of declarative region as used in [basic.scope.declarative]/4:
Given a set of declarations in a single declarative region, each of which specifies the same unqualified name, they shall all refer to the same entity, or [... = be function overloads], or [... = various exceptions].
This, as far as I can see, contradicts the definition given in [basic.scope.declarative]/1:
int main()
{
int x;
{
int x;
}
}
Here, we have two declarations specifying the same unqualified name. The outer x as a name is valid also inside the inner {}; yet, this is a perfectly legal C++ program. I suspect that declarative region in fact shouldn't be associated with a single name.
I think it is possible to simplify this definition of scope by using the terminals { and }.
This phrase
A name used in the definition of a class X outside of a member
function body...
considers all names that are used in the definition of a class that is starting from the class head and ending in the closing brace excluding names used in member functions (names used in member functions are considered in other paragraph).
For example
class B : public A
{
int x;
int a[i];
C z;
//..
};
So these names are A, x, a, i, C, z.
Take into account that though names x, a, and z are defined in the class their names can be used in other member definitions of the class.
As for your code example
class A { static const int a = 4; }
int b = A::a;
The name a after the nested-name-specifier used into the global scope or it used into the class scope?
then name a is searched in the class scope of class A but its qualified name used in the global scope to initialize variable b.
Consider another example though it has nothing common with the phrase you cited but has a relation with your code.
struct A
{
static int a;
static int b;
};
int A::a = 10;
int A::b = a;
Here is used name a without nested name specifier. It is one more rule how names are searched in the class scope.

Global scope vs global namespace

I saw usages of these two phrases: global scope and global namespace. What is the difference between them?
In C++, every name has its scope outside which it doesn't exist. A scope can be defined by many ways : it can be defined by namespace, functions, classes and just { }.
So a namespace, global or otherwise, defines a scope. The global namespace refers to using ::, and the symbols defined in this namespace are said to have global scope. A symbol, by default, exists in a global namespace, unless it is defined inside a block starts with keyword namespace, or it is a member of a class, or a local variable of a function:
int a; //this a is defined in global namespace
//which means, its scope is global. It exists everywhere.
namespace N
{
int a; //it is defined in a non-global namespace called `N`
//outside N it doesn't exist.
}
void f()
{
int a; //its scope is the function itself.
//outside the function, a doesn't exist.
{
int a; //the curly braces defines this a's scope!
}
}
class A
{
int a; //its scope is the class itself.
//outside A, it doesn't exist.
};
Also note that a name can be hidden by inner scope defined by either namespace, function, or class. So the name a inside namespace N hides the name a in the global namspace. In the same way, the name in the function and class hides the name in the global namespace. If you face such situation, then you can use ::a to refer to the name defined in the global namespace:
int a = 10;
namespace N
{
int a = 100;
void f()
{
int a = 1000;
std::cout << a << std::endl; //prints 1000
std::cout << N::a << std::endl; //prints 100
std::cout << ::a << std::endl; //prints 10
}
}
"Scope" is a more general term than "namespace". Every namespace, class and code block defines a scope in which names declared inside it can be used; a namespace is a container for names declared outside classes and functions.
"Global scope" and "global namespace" can be used more or less interchangeably; the scope of a name declared in a namespace covers the whole of that namespace. Use "namespace" if you're specifically referring to the namespace, and "scope" if you're referring to the visibility of names inside it.
When you declare a global variable int i for example, we say i is in the global namespace and has the global namespace scope. That's all.
Excerpt From C++03:
3.3.5 Namespace scope
The outermost declarative region of a translation unit is also a namespace, called
the global namespace. A name declared in the global namespace has global namespace
scope (also called global scope).
Scope denotes the lifetime of an object, you can have a global variable that will exist as long as your program executes, or you can have a variable with a block scope that will exist as long as that block of code executes. Consider this example:
#include <iostream>
int a = 100;
main () {
int a = 200;
std::cout << "local a is: " << a << std::endl;
std::cout << "global a is: " << ::a << std::endl;
return 0;
}
When executed the statement will print local a is: 200, that is expected obviously, because we're redefining a in main which leaves in the scope of it's enclosing block. We also print the global ::a which again prints the expected value 100, because we have asked for the global namespace ::.
A namespace semantics are mostly logical, it is a way of isolating symblos from one another, in the hope to avoid name clashes, it does not affect the lifespan of an object.
Scope on the other hand, denotes the lifespan of an object, the global a sprung into existence before the local a because it gets constructed much earlier than main gets executed. However, scope also forces a namespace on the symbol, but not in the same way that a namespace does. There are different kind of scopes, global, class, function, block, file etc...
The confusing part is that scope is sometimes overloaded to denote the visibility of a particular symbol, which is something borrowed from C, where the notion of namespaces did not exist and scope was used to denote both, lifespan and visibility. In C++, however the rules changed a bit,but the term scope is still used the same way because the two languages share a great deal of concepts.
#Dmitriy Ryajov
The topic is a little bit old but I want to offer my help about this. I think that you should not make things more complicated than they really are. Scope of an identifier is the part of a computer program where the identifier, a name that refers to some entity in the program, can be used to find the referred entity. So the term scope only applies to identifiers and we should not mix it with the lifetime of the object. They are somewhat connected but should not be mixed up. The lifetime of the object is denoted by where we allocate the memory for that object. So, for example, if a memory is allocated on the stack, it will be freed as soon as the function finishes. So it depends on where we store the object and that denotes its lifetime. The scope only says: "Here is a name for an object and we can use this name for the object till then and then". So, as I said, the term scope is only for identifiers of the objects and the lifetime is something else wich is denoted by where we store the object.
Additionally, I want to say something about linkage which is closely related to this. This can be also sometimes confusing. Let's say we have some identifiers in the translation unit that refer to some objects. Whether the same identifiers in other translation unit will refer to the same entities is denoted by the linkage. So, for example, if an identifier has an external linkage, we can refer to the entity that this identifier refers to but from other translation unit by declaring it with keyword extern. Now, let's say we don't want to use that entity in other translation units. Then, the entity will exist till the program finishes but when we don't declare it, we won't be able to refer to it. Also note that now i mixed the terms linkage and lifetime. But this is because only global entities have external linkage. An identifier inside a function can't be refered to from the other parts of the program.
Conclusion: Always try to keep things simple. I was surprised how different people talk about these terms differently. The whole process of separate compilation is confusing, because there are multiple terms which have almost the same meaning and probably everyone will get stuck at this point.

What does it mean if a method call starts with two colons?

A coworker routinely writes something like this:
::someObject->someMethod(anAttribute, anotherAttribute);
someObject is a global variable.
Those two colons seem strange to me. The code compiles and runs just fine without them.
The coworker claims that those colons make someObject explicitly global and thus prevent confusion with a possible local someObject. I would think that you would not be able to define someObject locally if it was already defined globally?
Could you shed some light on what those colons mean and whether they are necessary?
Your coworker is right. You can indeed define a local someObject which would hide the global someObject within that scope:
SomeClass* someObject = ...;
// here the global object is visible
someObject->someMethod(anAttribute, anotherAttribute); // calls the global object
void someMethod() {
SomeClass* someObject = ...;
// here the local object hides the global
::someObject->someMethod(anAttribute, anotherAttribute); // calls the global object
someObject->someMethod(anAttribute, anotherAttribute); // calls the local object
}
// here again only the global object is visible
someObject->someMethod(anAttribute, anotherAttribute); // calls the global object
Scopes can be embedded within other scopes recursively, thus you may have a namespace within global scope, a class within a namespace, an inner class within the class, a method within an inner class, a block within the method... etc. And you may have variables/classes/methods/... of identical names in any of these scopes. So identifying what entity a specific name is referring to is not a trivial task in C++. It is known as name lookup.
In brief, whenever the compiler finds a name, it looks up that name starting from the innermost scope. I.e. inside someMethod, the name someObject is matched by the object defined locally. ::someObject overrides this default behaviour and makes the compiler search only within the outermost (global) scope, thus it finds the global object instead ofthe local.
You can indeed define a someObject locally even though there is a global one. The two variables have different scope, so the compiler knows there's a difference between the two, and the double colons let you refer to the global one.
This also applies to classes outside of a namespace; i.e., to refer to a class Foo from the class Bar::Foo, you use ::Foo to tell the compiler you are talking about the one that isn't in a namespace.
Here's an example that shows it working:
#include<stdio.h>
int someInt = 4;
int main() {
int someInt = 5;
printf("%d", someInt+::someInt);
return 0;
}
If you compile and run that piece of code, it will output 9.
The coworker claims that those colons
make someObject explicitly global and
thus prevent confusion with a possible
local someObject.
Yes - it means the function can be, and must only be, matched in the global namespace. It makes it obvious you're dealing with a global, and would prevent accidental matching against something more local (beit function local, an object member, namespace member, in a namespace you're using, a Koenig lookup match etc.).
I would think that you would not be
able to define someObject locally if
it was already defined globally?
It would be a very bad idea to make it an error. Say a team of programmers decides they want to add a variable called "last_error" to their namespace: they shouldn't have to worry if existing functions in the namespace use the same name for a local variable. If you copy a function from one namespace or class to another, you shouldn't have to make error-prone identifier substitutions in the implementation.
Regarding the benefits of ::, consider:
namespace X
{
void fn() {
rip(data, bytes); // MP3 rip this data
}
}
...then fn() needs to be moved quickly into namespace Y...
namespace Y
{
void rip(const char* message, int exit_code); /* for fatal errors */
...
}
...a casual copy-paste into the guts of Y could easily overlook that log won't match the same global function it used to when fn was in namespace X, but - as illustrated - the functionality may differ markedly :-).
You can think of each namespace, class/struct and functions forming a tree, where each level must be uniquely keyed (i.e. no same-named classes in the same namespace), but decendents are always independent of each other and their ancestors. Increasing freedom to vary independently is essential for letting many people work simultaneously on a big problem.
Could you shed some light on what
those colons mean and whether they are
necessary?
In this specific usage, the :: probably isn't strictly necessary. It adds a little protection, but makes it harder to move the variable to a more local scope later - though that's not so important because the compiler will tell you about the places that continue to refer to ::x after x is moved.
Just a minor add on to all other nice points which have come in the response.
Basically :: invokes qualified name lookup in the global namespace. However it is not guaranteed to be problem free especially in the face of indiscriminate using directives.
The code shown illustrates an important property of qualified name lookup. The point here is that namespaces nominated by using directives in the global namspace are searched. However using directives in namespaces that have the name being searched are skipped.
namespace Z{
void f(){cout << 1;}
}
namespace Y{
void f(){cout << 2;}
using namespace Y; // This namespace is not searched since 'f' is found in 'Y'
}
#if 0
namespace Z{
void f(){cout << 3;}
using namespace Y; // This namespace is not searched since 'f' is found in 'Y'
}
using namespace Z;
#endif
using namespace Y;
int main(){
::f(); // Prints 2. There is no ambiguity
}
In the code shown, if lines with the #if directive are enabled, there is an ambiguity in resolving the name 'f'.

Query on Static member variables of a class in C++

Sorry if this question seems trivial to many here.
In a C++ code there is something as below:
class Foo
{
public:
static int bands;
...
...
private:
...
...
}//class definition ends
int Foo::bands; //Note: here its not initialized to any value!
Why is the above statement needed again when 'bands' is once declared inside the class as static?
Also can a static variable be declared as a private member variable in any class?
C++ notes a distinction between declaring and defining. bands is declared within the class, but not defined.
A non-static data member would be defined when you define an object of that type, but since a static member is not a part of any one specific object, it needs it's own definition.
a) It's needed because that's the way the languge is designed.
b) Static variables are initialized by their default constructor, or to zero for built-in types.
c) Yes, they can be (and usually are) private.
Take a look at this question.
It has to do with obj files, how they are used, and how memory addresses for globally scoped variables are ultimately discovered through the linking process. Object files contain the addresses of all global data and functions defined in the corresponding cpp. They layout some memory in a relative fashion to tell the liker where in that file these global vars/funcs can be found. So for example
function doFoo can be found 0 bytes from beginning of this file
int foo::bands can be found 12 bytes from beginning of this file
etc
Its almost easier to think about if you've done straight C before. In a pure C world you would do things in a more traditional modular programming sense. Your module would be defined with a header and a cpp. The header would define a "public" variable like below, using the extern keyword, then instantiate it in the cpp.
foo.h
extern int bands;
foo.cpp
#include "foo.h"
int bands;
foo.obj:
int bands can be found 0 bytes from the beginning of this file
The "extern" keyword states that this name is valid and its address will get resolved at link time. Everyone that included "foo.h" and wanted to use the "bands" global variable had could now use it. At link time, the linker would figure out that bands existed in the foo.obj. If you forgot to put "int bands" in foo.obj, you'd get a linker error, and have to go resolve it.
In C++ using static in a class declaration i similar. You are telling the users that there exists this thing called "foo::bands" and where it will live will get resolved at link time. Later down the line, the linker sees that in foo.obj, foo::bands exists, and all references to foo::bands can be resolved.
My understanding is that you would only need to declare Foo::bands if you planned on using it prior to ever creating an instance of your class. Basically, when you declare a static in a C++ class then only one copy of that variable exists for all instances of that class. However, you can't normally access Foo::bands until an instance of the class is declared.
For example:
Pointers to Members
#include <iostream>
using namespace std;
class X {
public:
int a;
void f(int b) {
cout << "The value of b is "<< b << endl;
}
};
int main() {
// declare pointer to data member
int X::*ptiptr = &X::a;
// declare a pointer to member function
void (X::* ptfptr) (int) = &X::f;
// create an object of class type X
X xobject;
// initialize data member
xobject.*ptiptr = 10;
cout << "The value of a is " << xobject.*ptiptr << endl;
// call member function
(xobject.*ptfptr) (20);
}