Наткнулся на сабж, VS2005
Минимальный пример таков:
Test1.cpp
#include "Test1.h"
#include <string>
class something
{
public:
int a;
std::string sz1;
int b;
std::string sz2;
};
void CTest1::test()
{
something smth;
smth.b = 0x7fffffff;
smth.sz2 = "qwefqwefqwefqwef";
}
Test3.cpp
#include "StdAfx.h"
#include <string>
#include "Test3.h"
class something
{
public:
std::string sz1;
std::string sz2;
int a;
};
void CTest3::test()
{
something smth;
smth.a = 0x7fffffff;
smth.sz1 = "asdfasdfasdfsadf";
smth.sz2 = "rtyjrtyjrtyjrtyjrtyj";
}
int main()
{
CTest1 t1;
CTest3 t3;
t1.test();
t3.test(); //здесь падает на вызове smth.sz1 = "asdfasdfasdfsadf", видимо компилятор/линкер путает структуры
return 0;
}
Ни ерроров, ни ворнингов на 4 уровне.
Отсюда возникает вопрос, каково должно быть поведение компилятора/линкера, если в двух cpp файлах встречаются структуры/классы с одинаковым именем?
Ты нарушаешь ODR и наблюдаешь лишь следствие этого. Исправляется ситуация просто:
Test1.cpp:
...
namespace {
class something
{
public:
int a;
std::string sz1;
int b;
std::string sz2;
};
}
...
Test3.cpp:
...
namespace {
class something
{
public:
int a;
std::string sz1;
int b;
std::string sz2;
};
}
...
Здравствуйте, Анатолий Широков, Вы писали:
АШ>Ты нарушаешь ODR и наблюдаешь лишь следствие этого. Исправляется ситуация просто:
Спасибо,
Занимался рефакторингом большого класса, вот и получилось, что получилось
Я удивился, что линкер молчит
Здравствуйте, dcb-BanDos, Вы писали:
DB>Я удивился, что линкер молчит
А что линкеру-то говорить?
Представь себе, что твой класс (твои классы) вынесен(ы) в хедеры, которые включены в кучу компилируемых исходников.
Компилятор максимум, что может сделать — это нарожать в каждом объектом файле по копии функций (в твоём конкретном случае — это неявно определённые конструкторы, присваивание и деструктор) с пометкой selectany. Причём что-то он проинлайнит, а что то будет вызывать.
Затем линкер оставит по одному экземпляру каждой такой функции.
Диагностировать нарушение ODR можно, только снабдив каждый selectany-экземпляр некой сигнатурой — свёрткой его определения.
Но это, мне кажется, неподъёмное дело. Придётся тащить в свёртку все зависимости (сигнатуры всех упомянутых в функции типов, функций, переменных).
И оградиться от ложных тревог (два функционально эквивалентных экземпляра с разными сигнатурами — например, из-за несущественных расхождений в зависимостях).
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>