непонятное поведение
От: dcb-BanDos Россия  
Дата: 28.09.09 12:54
Оценка:
Наткнулся на сабж, 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 файлах встречаются структуры/классы с одинаковым именем?
Ничто не ограничивает полет мысли программиста так, как компилятор.
Re: непонятное поведение
От: Анатолий Широков СССР  
Дата: 28.09.09 12:58
Оценка:
Ты нарушаешь 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;
};
}
...
Re[2]: непонятное поведение
От: dcb-BanDos Россия  
Дата: 28.09.09 13:45
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

АШ>Ты нарушаешь ODR и наблюдаешь лишь следствие этого. Исправляется ситуация просто:


Спасибо,
Занимался рефакторингом большого класса, вот и получилось, что получилось
Я удивился, что линкер молчит
Ничто не ограничивает полет мысли программиста так, как компилятор.
Re[3]: непонятное поведение
От: Кодт Россия  
Дата: 28.09.09 15:58
Оценка:
Здравствуйте, dcb-BanDos, Вы писали:

DB>Я удивился, что линкер молчит


А что линкеру-то говорить?
Представь себе, что твой класс (твои классы) вынесен(ы) в хедеры, которые включены в кучу компилируемых исходников.
Компилятор максимум, что может сделать — это нарожать в каждом объектом файле по копии функций (в твоём конкретном случае — это неявно определённые конструкторы, присваивание и деструктор) с пометкой selectany. Причём что-то он проинлайнит, а что то будет вызывать.
Затем линкер оставит по одному экземпляру каждой такой функции.

Диагностировать нарушение ODR можно, только снабдив каждый selectany-экземпляр некой сигнатурой — свёрткой его определения.
Но это, мне кажется, неподъёмное дело. Придётся тащить в свёртку все зависимости (сигнатуры всех упомянутых в функции типов, функций, переменных).
И оградиться от ложных тревог (два функционально эквивалентных экземпляра с разными сигнатурами — например, из-за несущественных расхождений в зависимостях).
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.