Re[2]: компилятору жестоко рвёт крышу :(
От: blackhearted Украина  
Дата: 22.07.11 12:51
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Здравствуйте, nen777w, Вы писали:


IRO>Ответ дан выше, есть еще похожий баг, когда конструкторы срабатывают коректно, а вот из за того что у них есть виртуальные деструкторы, начинается сказка при удалении, багу искали пару дней, потом я нечайно ее заметил


IRO>Вопрос такой, разве тяжело давать варнинг/еррор в линкере когда он находит два определения?


w4 не показывает?
Re[6]: компилятору жестоко рвёт крышу :(
От: nen777w  
Дата: 22.07.11 13:18
Оценка:
N>>
N>>namespace
N>>{
N>>   struct S
N>>   {
N>>      ....
N>>   }
N>>}

N>>class impl : public impl_t<S> {}; <-- Я так понимаю здесь возникает та же проблема?
N>>


N>>Решение поместить эту строчку в этот же анонимный неймспейс?

AF>Зачем? S, упомянутый выше в impl_t<S> и будет из этого анонимного namespace. Анонимный namespace автоматом раскрывается как после using'а именованного.

да вот затем что опять какая то фигня выходит:


//tpl_h.h
template<typename T>
struct t_impl
{
  void foo( const T& arg ) {}
};



//a.h
namespace TEST
{
   //fw
   struct a_impl;
  
   class A
   {
   private:
     a_impl* pImpl;
     a_impl get_impl() { return pImpl; }

   public:
     A();
     void doo();
   }
}

//a.cpp

using namespace A;

namespace
{
   struct S //имя этой структуры повторяется в нескольких модулях: a.cpp, b.cpp, d.cpp ...
   {
     S(){}
   };
}

namespase A {
   struct a_imp : public t_impl<S> {};
}

//конструктор
A::A() : pImp( new a_imp() ) {}

//метод doo

void A::doo()
{
   S s; //<-- тут буден вызван правильный конструктор
   
   get_impl()->foo(s); //<-- а вот тут когда мы прийдём в метод t_impl::foo() аргумент какого то фига будет другого типа  :xz: 
                       //сужу потому как у него даже будет другой набор полей
}


или меня дебагер дурит или Я чо вообще происходит с линкером
Re[7]: компилятору жестоко рвёт крышу :(
От: nen777w  
Дата: 22.07.11 13:28
Оценка:
короче отбой это у компилятора subj
Re[7]: компилятору жестоко рвёт крышу :(
От: Alexey F  
Дата: 22.07.11 13:53
Оценка:
Здравствуйте, nen777w, Вы писали:
N>namespace
N>{
N>   struct S //имя этой структуры повторяется в нескольких модулях: a.cpp, b.cpp, d.cpp ...
N>   {
N>     S(){}
N>   };
N>}


А эти строки:
N>namespase A {
N>   struct a_imp : public t_impl<S> {};
N>}

упоминаются только в a.cpp? Или в b.cpp, c.cpp, d.cpp есть такое же определение a_imp(l?)?
(На всякий случай: rebuild после оборачивания всех S в anonymous namespace был сделан?).
Re[8]: компилятору жестоко рвёт крышу :(
От: nen777w  
Дата: 22.07.11 14:14
Оценка:
AF>упоминаются только в a.cpp? Или в b.cpp, c.cpp, d.cpp есть такое же определение a_imp(l?)?
AF>(На всякий случай: rebuild после оборачивания всех S в anonymous namespace был сделан?).

уже разобрался, написал постом выше. всё нормально с кодом.
это у дебагера едет крыша, а Я ему верю.
Re: компилятору жестоко рвёт крышу :(
От: ononim  
Дата: 22.07.11 14:46
Оценка:
на всякий случай:

7.1.2
3- A function defined within a class definition is an inline function. The inline specifier shall not appear on a block scope function declaration.*
4- An inline function shall be defined in every translation unit in which it is used and shall have exactly the same definition in every case (basic.def.odr).

Как много веселых ребят, и все делают велосипед...
Re[3]: компилятору жестоко рвёт крышу :(
От: IROV..  
Дата: 22.07.11 15:11
Оценка:
Здравствуйте, blackhearted, Вы писали:

B>w4 не показывает?


ВаСя 2010 не показывает
я не волшебник, я только учусь!
Re: компилятору жестоко рвёт крышу :(
От: vdimas Россия  
Дата: 22.07.11 17:15
Оценка:
Здравствуйте, nen777w, Вы писали:

N>Такая проблема.

N>есть совершенно два разных cpp файла в которых в namespace определена одна и та же структура:

Ну так что пугает? Пользовательский конструктор у них одинаковый.

Вот еще пример, с разными именами и даже разными типами:

struct S1 {
  float field1;
  virtual float m1() const { return field1; }
};

struct S2 {
  int field2;
  virtual int m2() const { return field2; }
};


При включенной оптимизации и совпадении sizeof(float) и sizeof(int) тело метода m1 и m2 будет одно на двоих, как и адрес в vtable обоих типов. Имена тут не при чем.
Здесь нет никакого бага, это же внутреннее дело компилятора. Тоже самое наблюдается для численных литералов, уже обсуждалось: http://rsdn.ru/forum/flame.comp/3782092.1.aspx
Автор: vdimas
Дата: 21.04.10


Без такой оптимизации мы бы имели проблему как в первых компиляторах С++, поддерживающих шаблоны — очень большой бинарник. А тут имеет место "склейка" идентичных участков кода, поэтому готовый бинарник, порождаемый MSVC порой более чем в 2-3 раза меньше, чем порождаемый gcc.
Re[2]: компилятору жестоко рвёт крышу :(
От: IROV..  
Дата: 22.07.11 19:08
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, nen777w, Вы писали:


N>>Такая проблема.

N>>есть совершенно два разных cpp файла в которых в namespace определена одна и та же структура:

V>Ну так что пугает? Пользовательский конструктор у них одинаковый.

Тут не пугает, тут бага.

твой пример это оптимизация, которая не влияет на семантику.
А в случае автора — баг, который меняет семантику(ожидаемый результат)

я не волшебник, я только учусь!
Re[2]: компилятору жестоко рвёт крышу :(
От: Dmi3S Россия http://dmi3s.blogspot.com/
Дата: 23.07.11 08:59
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Вопрос такой, разве тяжело давать варнинг/еррор в линкере когда он находит два определения?


Есть такая вещь как инстанциация шаблонов. Например, в разных единицах трансляции несколько раз инстанцируется std::max<int>(). Задача линкера, уже ничего не знающего о шаблонах, дать выжить только одной инстанциации в конечном исполняемом файле. Думаю, поэтому затруднительно выдавать предупреждение в каких-то специфичных случаях: не очень ясно, как можно быстро проверить эквивалентность функций. Впрочем, как это сделать не быстро, тоже не ясно .
Re[7]: компилятору жестоко рвёт крышу :(
От: wander  
Дата: 23.07.11 09:17
Оценка:
Здравствуйте, blackhearted, Вы писали:

B>Здравствуйте, uzhas, Вы писали:


U>>Здравствуйте, blackhearted, Вы писали:


B>>>static не поможет?

U>>а куда выхотите его приписать?
U>>static namespace? static struct? в этих случаях не поможет

B>точно это же definition... признаю совю неправоту


Я даже больше скажу: ключевое слово static не рекомендуется к использованию в таком контексте:

7.3.1.1/2
The use of the static keyword is deprecated when declaring objects in a namespace scope, the unnamed-namespace provides a superior alternative.

Re[3]: компилятору жестоко рвёт крышу :(
От: IROV..  
Дата: 23.07.11 09:28
Оценка:
Здравствуйте, Dmi3S, Вы писали:

DS>Здравствуйте, IROV.., Вы писали:


IRO>>Вопрос такой, разве тяжело давать варнинг/еррор в линкере когда он находит два определения?


DS>Есть такая вещь как инстанциация шаблонов. Например, в разных единицах трансляции несколько раз инстанцируется std::max<int>(). Задача линкера, уже ничего не знающего о шаблонах, дать выжить только одной инстанциации в конечном исполняемом файле. Думаю, поэтому затруднительно выдавать предупреждение в каких-то специфичных случаях: не очень ясно, как можно быстро проверить эквивалентность функций. Впрочем, как это сделать не быстро, тоже не ясно .


с функциями проблем никогда небыло, были проблемы с методами
я не волшебник, я только учусь!
Re[4]: компилятору жестоко рвёт крышу :(
От: Dmi3S Россия http://dmi3s.blogspot.com/
Дата: 23.07.11 09:46
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Здравствуйте, Dmi3S, Вы писали:


DS>>Здравствуйте, IROV.., Вы писали:


IRO>>>Вопрос такой, разве тяжело давать варнинг/еррор в линкере когда он находит два определения?


DS>>Есть такая вещь как инстанциация шаблонов. Например, в разных единицах трансляции несколько раз инстанцируется std::max<int>(). Задача линкера, уже ничего не знающего о шаблонах, дать выжить только одной инстанциации в конечном исполняемом файле. Думаю, поэтому затруднительно выдавать предупреждение в каких-то специфичных случаях: не очень ясно, как можно быстро проверить эквивалентность функций. Впрочем, как это сделать не быстро, тоже не ясно .


IRO>с функциями проблем никогда небыло, были проблемы с методами


А есть разница между функциями и методами на стадии линковки?
Re[8]: компилятору жестоко рвёт крышу :(
От: Masterkent  
Дата: 23.07.11 10:38
Оценка: 9 (3)
wander:

W>Я даже больше скажу: ключевое слово static не рекомендуется к использованию в таком контексте:

W>

W>7.3.1.1/2
W>The use of the static keyword is deprecated when declaring objects in a namespace scope, the unnamed-namespace provides a superior alternative.

Комитет по стандартизации уже поменял свою точку зрения на этот счёт: DR 1012 "Undeprecating static"
Re[3]: компилятору жестоко рвёт крышу :(
От: nen777w  
Дата: 23.07.11 19:22
Оценка:
Здравствуйте, Dmi3S, Вы писали:

DS>Здравствуйте, IROV.., Вы писали:


IRO>>Вопрос такой, разве тяжело давать варнинг/еррор в линкере когда он находит два определения?


DS>Есть такая вещь как инстанциация шаблонов. Например, в разных единицах трансляции несколько раз инстанцируется std::max<int>(). Задача линкера, уже ничего не знающего о шаблонах, дать выжить только одной инстанциации в конечном исполняемом файле. Думаю, поэтому затруднительно выдавать предупреждение в каких-то специфичных случаях: не очень ясно, как можно быстро проверить эквивалентность функций. Впрочем, как это сделать не быстро, тоже не ясно .


предположительно это могли бы быть подсказки от компилятора, ему то об этом известно всё, хотя может Я не могу охватить всех специфических случаев.
Re[6]: компилятору жестоко рвёт крышу :(
От: rg45 СССР  
Дата: 23.07.11 20:33
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, nen777w, Вы писали:

N>>Как это правильно называется что бы "ликбез почитать"?
U>external linkage
U>http://stackoverflow.com/questions/1358400/what-is-external-linkage-and-internal-linkage-in-c

Маленькое уточнение. Ты все правильно говоришь, но, возможно, не совсем точно — при чтении твоих постов может сложиться неверное мнение, будто бы все сущности, определенные в анонимных пространствах имен, автоматом получают внутреннее связывание. В анонимных пространствах имен действуют те же правила, что и в обычных — константы по умолчанию получают внутреннее связывание, функции, переменные и классы — внешнее. Только сами пространства имен изолированы от внешнего мира.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[4]: компилятору жестоко рвёт крышу :(
От: Dmi3S Россия http://dmi3s.blogspot.com/
Дата: 23.07.11 23:03
Оценка:
Здравствуйте, nen777w, Вы писали:

N>предположительно это могли бы быть подсказки от компилятора, ему то об этом известно всё, хотя может Я не могу охватить всех специфических случаев.


Компилятору известно далеко не все, а только единица трансляции. Да и какие "подсказки" ему давать линкеру, у которого на входе уже действительно все, даже с излишком?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.