Argument dependent name lookup

Argument dependent name lookup ( often argument dependent lookup or short ADL to German argument -dependent name resolution; earlier Koenig lookup for the computer scientist Andrew Koenig ) is a technique in programming languages ​​with support for both namespaces as well as free functions under certain circumstances symbols from other namespaces to import automatically. An example is the programming language C .

Survey

A simple example of ADL in C , the use of the stream classes is:

# include   int main () {    std :: cout << " Hello, world!" << Std :: endl; } In this example, the stream function operator << operator is used, the namespace is defined in h, as the remaining stream classes. Without using the above example would thus ADL not work. You would have to either move the corresponding code in the std namespace, or explicitly by the operator

Using std :: operator <<; import. But even this does not solve the underlying problem, because at least if custom data types to be used from several different namespaces together with the stream classes in std, are usually different definitions of operator << in different namespaces before.

It is also possible to completely forgo the infix notation:

# include   int main () {    std :: operator << (std :: cout, " Hello, World "), operator << (std :: endl ). ; } The postfix notation allows the qualification of function calls with the appropriate namespaces, however, is considerably more paperwork. In addition, the need for a postfix call would significantly restrict even in simple examples such as the above, the usefulness of particular operator overload. Therefore, the C standard specifies (Section 3.4.2) that the compiler needs to the argument types associated namespaces ( the so-called " associated namespaces " ) in the search.

The " interface " principle in C

The reason that argument -dependent name resolution in C is necessary is ultimately the interpretation of what one perceives as the class interface of a class. In contrast to most other languages, C interprets a function as belonging to a class when one hand accepted the arguments of the class type and the other hand in the same namespace as the class is. ADL allows to largely make use of such features as free as if they were directly part of the class interface.

An application example of the interface principle in turn provide the stream classes of the standard library dar. To own data types with the standard streams to use, you would have otherwise for each new class extend the stream classes, so that they can deal with it. This is not practical. Operator definitions for output to streams can therefore not be methods of stream classes, but must be implemented as free functions.

Such functions are also very closely linked to the class whose stream output they provide. For this reason, they are usually defined in the same namespace as the class. The ADL mechanism then makes it possible to consider them in the resolution of operator overload:

# include   namespace geometry {    struct Vector2D    {      Vector2D (): x (0), y ( 0) { }      Vector2D (double x_new, double y_new ): x ( x_new ), y ( y_new ) {}      double x;      double y;    };      std :: basic_ostream & operator << (std :: basic_ostream & stream, const Vector2D & v )    {      stream << " ( " << v.x << ", " << v.y << " )";      return stream;    } }   int main () {    Geometry :: Vector2D V (1, 2);      std :: cout << v << std :: endl; } trouble

The argument -dependent resolution of symbols can lead to subtle errors and unportablem code between different implementations. Another problem is occasional counter - intuitive behavior of the compiler at the ADL resolution, especially when using using statements.

The problems encountered by argument -dependent name resolution (mainly accidental overloading) are basically the same that occur in programming languages ​​without namespaces. Therefore, they represent a limitation of the protective function of namespaces.

If the function name is to be resolved, for example, identical to a function from the namespace std, it may happen that the compiler selects this function instead of the intended by the programmer, since initially all associated namespaces are imported. Afterwards, concrete function is selected (even if the programmer has requested a specific version by using directive ) based on the signatures.

For example, the following program can not be translated by any C implementation:

# include   namespace N {    struct X {};      template    int * operator (T, unsigned int i)    {      return i 1;    } }   int main () {    std :: vector v ( 5);    const N :: X & elem = v;      / / (...) } Whether the above program can be translated as, ultimately, by the implementation of vector. In some implementations, the access member is implemented on iterators v, is applied to the turn operator (). Depending on the implementation details, it may happen that the namespace N considered as an associated namespace resolution in the iterator access and the above implementation of the " " operator is used incorrectly. To make matters worse, that any error messages come from the standard library, which greatly complicates diagnosis. In the worst possible case, the compiler translates the program without error, but generates the wrong code.

Further problems are caused by individual compiler implementation errors in the ADL resolution. The differences in the standard libraries and compilers are the reason why a program, for example, in translation with GNU C may behave differently than with Microsoft Visual C .

Alternatives

Other programming languages ​​such as Java or C # come from without argument -dependent name resolution. This is mainly because these programming languages ​​are object-oriented stricter. C is a multi -paradigm language that does not force an object-oriented work, and its standard library rather than genericity based on object orientation in contrast.

In strict object- oriented languages, all user-defined types are normally represents classes that inherit from a common base (usually Object od.ä. ). The base class defines a basic interface that is provided with it from any custom types. The above example of the input and output using standard functions is solved in these languages ​​so on object orientation and virtual methods.

Recent Developments

Due to various formulation gaps in the C standard, there were times in the past proposals, such as the current ADL mechanism in C could be adjusted in order to avoid unexpected behaviors by the programmer as possible and also to improve the compatibility between different implementations.

A proposal of the computer scientist David Abrahams 2004 was the introduction of so-called " explicit" namespaces, should be where the ADL - resolution de facto eliminated or significantly reduced. Another suggestion by Herb Sutter saw certain restrictions of ADL Resolution should uphold the broad compatibility with existing code and yet at the same time resolve the major difficulties.

The current C standard ( C 11) does not consider these proposals, however, defines the ADL algorithm in more detail than in previous versions ( in particular, several cases are now defined, in which ADL makes no sense and should not be performed by the compiler ).

76707
de