Difference between name lookup and name binding in C++ - c++

In C++, is there a difference between name binding and name lookup in? The working draft C++14 standard (N4296) defines name lookup in (3.4) as
Name lookup associates the use of a name with a declaration (3.1) of that name.
I can't find a definition for name binding in the standard, but the IBM Knowledge Center documentation for their XL C/C++ compiler defines:
Name binding is the process of finding the declaration for each name that is explicitly or implicitly used in a template.
The only distinctions between the two definitions seem to be that (1) name binding refers specifically to a name used in a template and (2) name binding refers to a name, while name lookup refers to the use of a name.
However, Section (13.3) on Overload Resolution in the C++ standard mentions binding frequently, but without defining it. The way 'binding' is used in this context makes it seem that binding refers to the association of an argument with a function parameter.
At first, this definition seems different from either of the other two definitions, thought it fits (broadly) the definition of name lookup if we assume that the name of the function is being bound to its declaration by comparing the types of arguments and parameters. That isn't exactly the sense used in Section (13.3), but I'm trying to make sense of the standard without a proper definition.
In short, if anyone has a good definition of 'name binding' or 'binding', I'd be grateful.

Having read the relevant parts of Wilson & Clark Comparative Programming Languages, I think I have a better understanding of the topic. If I surmise correctly, the term 'binding' covers a gamut of related terms, including name-declaration binding, name–type binding, declaration-reference binding, reference-value binding, and name-value binding.
"Name lookup" seems to be a synonym for name-declaration binding. The other uses of 'binding' in the C++14 standard relate to various combinations of the other varieties of binding.
Please correct me if I'm wrong!

Related

What is the difference between a name and a variable in C++

According to C++ ISO Draft (2020) 6.1 (Basics) :
A name is a use of an identifier (5.10), operator-function-id (12.6),
literal-operator-id (12.6.8), conversion-function-id (11.4.7.2), or
template-id (13.3) that denotes an entity or label (8.7.5, 8.2).
Every name that denotes an entity is introduced by a declaration.
Every name that denotes a label is introduced either by a goto
statement (8.7.5) or a labeled-statement (8.2).
A variable is introduced by the declaration of a reference other than
a non-static data member or of an object. The variable’s name, if any,
denotes the reference or object
A name can denote a entity, so it can denote an object and is introduced by a declaration in this case. A variable may be introduced by the declaration of an object, and in this case denotes the object. If I'm not misunderstading, the definitions of name and variable look very similar. What is the difference between a name and a variable?
(Particularly in the case that there is an intersection, e.g when they denote an object)
What is the difference between a name and a variable?
The most obvious (based upon your first quote) difference is that a name is more general than a variable. Every variable has a name, but not every name is of a variable. There are also names of functions, classes, operators, and templates. (This is not intended to be a complete list.)
Less obviously, a name is more specific than a variable, in the sense that a variable's name is only one aspect of the variable. I think your confusion comes from the fact that the name of a variable is necessarily introduced at the same time as the variable itself (your second and third quotes), and they go out of scope at the same time. There is no temporal separation of the two.
(Particularly in the case that there is an intersection, e.g when they denote an object)
I see this as somewhat philosophical. Let's take a similar situation: what is the difference between your name and yourself? Are you more than just a name? And yet, to identify you, others use your name.
It's not that different for variables. A variable has a name. That name is used to refer to the variable, often treated as being the variable. And yet, a variable is more than just a name; it also has a type and a value. The name does not intrinsically determine the type and value, yet out of convenience it is often used that way when talking about code. (That's not a bad thing, in the vast majority of cases.)
I would say that a variable has two things: a name and a value.
As far as names are concerned: variables can have names, but also functions, classes, ...
So a variable is an element, belonging to the C++ world (and lots of other programming languages).
A name is a property of much elements, such as variables, but also other ones.

What is a fully qualified name?

As far as I can tell, the term fully qualified isn't mentioned in the standard (e.g.), but I can recall "hearing" it many times online.
What do people mean when they say a name is fully qualified?
Does this count?
A::f()
or only this?
::A::f()
And, if it is standard, which wording have I not found?
An identifier that uses the scope resolution operator is a qualified name as per [expr.prim.id.qual]. Otherwise it is unqualified.
The standard doesn't define the meaning of fully qualified, but it does mention it in [library]/[requirements]/[organization]/[contents] which says (quote from standard draft)
Whenever a name x defined in the standard library is mentioned, the name x is assumed to be fully qualified as ::std::x, unless explicitly described otherwise.
For example, if the Effects: element for library function F is described as calling library function G, the function ::std::G is meant.
Wikipedia defines Fully qualified name:
In computer programming, a fully qualified name is an unambiguous name that specifies which object, function, or variable a call refers to without regard to the context of the call
Only a name qualified starting from the global namespace is unambiguous without context. This is the common usage.
Indeed, it is not a standard term. It has no definition in the standard.
However, the phrase "fully qualified" appears exactly once, in [contents] (15.5.1.1 "Library contents" in the as-of-writing most current draft N4800) paragraph 3:
Whenever a name x defined in the standard library is mentioned, the name x is assumed to be fully qualified as ::std::x, unless explicitly described otherwise.
So in this definition, only names starting with :: are fully qualified.

What is the meaning of the last sentence in [basic.lookup]/1?

[basic.lookup]/1:
The name lookup rules apply uniformly to all names (including typedef-names (10.1.3), namespace-names
(10.3), and class-names (12.1)) wherever the grammar allows such names in the context discussed by a
particular rule. Name lookup associates the use of a name with a set of declarations (6.1) of that name. The
declarations found by name lookup shall either all declare the same entity or shall all declare functions; in the
latter case, the declarations are said to form a set of overloaded functions (16.1). Overload resolution (16.3)
takes place after name lookup has succeeded. The access rules (Clause 14) are considered only once name
lookup and function overload resolution (if applicable) have succeeded. Only after name lookup, function
overload resolution (if applicable) and access checking have succeeded are the attributes introduced by the
name’s declaration used further in expression processing (Clause 8).
What are those attributes introduced by the names´s declaration?
This sentence is visible in the N1638 - C++ Working Draft from April 2004, so it doesn't refer specifically to attributes of the form [[...]], which were introduced to the standard by N2761 - Towards support for attributes in C++
(Revision 6) in 2008.
[basic.lookup]/1
Only after name lookup, function overload resolution (if applicable) and access checking have succeeded are the attributes introduced by the name’s declaration used further in expression processing (clause 5).
Also [basic.def]/1
A declaration (clause 7) introduces names into a translation unit or redeclares names introduced by previous declarations. A declaration specifies the interpretation and attributes of these names.
From the above, and looking at the five other occurrences of 'attribute' in that paper, it appears to me that 'attribute' just means "information about the name". So in this case, things like extern, friend, the body of a function definition, and anything else you can say about a name in a declaration, that wasn't part of determining the interpretation of a name.
Since C++11 this would also include "generalised attributes" in the form [[..]]. There's a hint here, N2761 didn't introduce 'attributes', it just gave us a generalised syntax for them.
Function parameters, conversely, would not be 'attributes' in this sense, as the interpretation of the function name involves the parameters as part of overload resolution. The return type would be an attribute, since we don't look at it until we know what the name means, and which overload we've chosen.
In a slightly-more-standardese sense, I think you can say that the 'specifiers' are attributes, while the 'declarators' specify the interpretation of a name.
Pratically, I would say (without checking for a more-specific rule) that this is the rule that requires that deleted functions survive all the way through the lookup and name resolution process, and then fail the compilation.
Otherwise, a crafty compiler author might want to save their users some grief by eliminating deleted functions earlier, on the grounds that you can't call a deleted function, so why bother including it in the overload set?

Does C++ use static name resolution or dynamic name resolution?

I have been reading about "Name resolution" in wikipedia (Name resolution WIKI) and it has been given in that that C++ uses "Static Name Resolution". If that is true then I couldn't figure out how C++ manages to provide "polymorphism" without using dynamic name resolution.
Can anyone please answer whether C++ uses "Static Name Resolution" or "Dynamic Name Resolution". If it is static, can you also explain how C++ provides polymorphism.
Wikipedia's definition of name resolution is about how tokens are resolved into the names of constructs (functions, typenames, etc). Given that definition, C++ is 100% static with its name resolution. Every token that represents an identifier must be associated at compile-time with a specific entity.
C++ polymorphism is effectively cheating. The compiler can see that a static name resolves to a member function defined with the virtual keyword. If the compiler sees that the object you are calling this on is a dynamic object (ie: a pointer/reference to that type rather than a value of that type), the the compiler emits special code to call that function.
This special code does not change the name it resolves to. What it changes is the function that eventually gets called. That is not dynamic naming; that is dynamic function dispatch. The name gets resolved at compile-time; the function gets resolved at runtime.
C++ use static name resolution because it renames each function to made each one have an unique.
That mean that the function int foo(int bar) will be known by the compiler as something like _Z3fooi, while int foo(float bar) will be known as something like _Z3foof.
This is what we call name mangling.

List of C++ name resolution (and overloading) rules

Where I can find a list of the rules that a C++ compliant compiler must apply in order to perform names resolution (including overloading)?
I'd like something like a natural-language algorithm or flow chart.
C++ standard of course has this set of rules but it is build up as new language statements are introduced and the result it's pretty hard to remember.
To make a long story short, I'd like to know the complete and detailed answer to the question "What compiler do when it see the name 'A'?"
I know C++ is all "We do this when X but not Y if Z holds" so, I'm asking whether it is possible to make it more linear.
EDIT: I'm working on a draft of this topic, something that may be improved collectively once posted. However i'm very busy this days and it may take time to have something publicable. If someone interested i'll promote the "personal note on a raw txt file" to something better and post it.
Well, in broad strokes:
If the name is preceded by ::, as in ::A or X::A, then use qualified name lookup. First look up X, if it exists (if not use the global namespace) then look inside it for A. If X is a class, and A is not a direct member, then look in all the direct bases of X. If A is found in more than one base, fail.
Otherwise, if the name is used as a function call such as A( X ), use argument-dependent lookup. This is the hard part. Look for A in the namespace the type of X was declared in, in the friends of X, and if X is a template instantiation, likewise for all the arguments involved. Scopes associated only by typedef do not apply. Do this in addition to unqualified lookup.
Start with unqualified lookup if argument-dependent lookup doesn't apply. This is the usual way variables are found. Start at the current scope and work outwards until the name is found. Note that this respects using namespace directives, which the other two cases do not.
Simply glancing at the Standard will reveal many exceptions and gotchas. For example, unqualified lookup is used to determine whether the name is used as a function call, as opposed to a cast-expression, before ADL is used to generate a list of potential overloads. Unqualified lookup doesn't look for objects in enclosing scopes of nested of local classes, because such objects might not exist at the time of reference.
Apply common sense, and ask more specific questions when (as often it does) intuition fails.