Немного о поиске имён линкером
От: nen777w  
Дата: 10.01.18 10:32
Оценка: -1
  "Немного кода:"
//Ii.h
struct Ii
{
    virtual void foo() = 0;
};


//a.h
#include "Ii.h"

namespace test
{
    struct A
    {
        Ii * foo();
    };
}


//b.h
#include "Ii.h"

namespace test
{
    struct B
    {
        Ii * foo();
    };
}


//a.cpp
#include <iostream>

namespace test
{
    struct IImp : Ii
    {
        IImp()
        {
            std::cout << "This is test::IImp() from a.cpp" << std::endl;
        }

        void foo()
        {
            std::cout << "This is test::IImp::foo() from a.cpp" << std::endl;
        }
    };

    Ii * A::foo()
    {
        return new IImp();
    }
}


//b.cpp
#include <iostream>

namespace test
{
    struct IImp : Ii
    {
        IImp(int)
        {
            std::cout << "This is test::IImp() from b.cpp" << std::endl;
        }

        void foo()
        {
            std::cout << "This is test::IImp from b.cpp" << std::endl;
        }
    };

    Ii * B::foo()
    {
        return new IImp(0);
    }
}


int main()
{
    test::B b;
    Ii *p = b.foo();
    p->foo();

    return 0;
}


Напечатает:

This is test::IImp() from b.cpp
This is test::IImp::foo() from a.cpp


Понятно что поиск имен линкер производит не локально а то в каком порядке компилятор будет собирать модули.
Понятно что анонимный namespace решает проблему т.к. об уникальности его имени компилятор позаботится.
Непонятно почему этот код допускается, почему например при генерации имен компилятор не может пометить для линкера что приоритет поиска адреса за именем нужно выполнять локально? Из-за возможности его форвардной декларации?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.