Здравствуйте, IROV.., Вы писали:
IRO>Здравствуйте, nen777w, Вы писали:
IRO>Ответ дан выше, есть еще похожий баг, когда конструкторы срабатывают коректно, а вот из за того что у них есть виртуальные деструкторы, начинается сказка при удалении, багу искали пару дней, потом я нечайно ее заметил
IRO>Вопрос такой, разве тяжело давать варнинг/еррор в линкере когда он находит два определения?
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'а именованного.
//a.hnamespace TEST
{
//fwstruct a_impl;
class A
{
private:
a_impl* pImpl;
a_impl get_impl() { return pImpl; }
public:
A();
void doo();
}
}
//a.cppusing 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() ) {}
//метод doovoid A::doo()
{
S s; //<-- тут буден вызван правильный конструктор
get_impl()->foo(s); //<-- а вот тут когда мы прийдём в метод t_impl::foo() аргумент какого то фига будет другого типа :xz:
//сужу потому как у него даже будет другой набор полей
}
или меня дебагер дурит или Я чо вообще происходит с линкером
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 был сделан?).
AF>упоминаются только в a.cpp? Или в b.cpp, c.cpp, d.cpp есть такое же определение a_imp(l?)? AF>(На всякий случай: rebuild после оборачивания всех S в anonymous namespace был сделан?).
уже разобрался, написал постом выше. всё нормально с кодом.
это у дебагера едет крыша, а Я ему верю.
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).
Как много веселых ребят, и все делают велосипед...
При включенной оптимизации и совпадении sizeof(float) и sizeof(int) тело метода m1 и m2 будет одно на двоих, как и адрес в vtable обоих типов. Имена тут не при чем.
Здесь нет никакого бага, это же внутреннее дело компилятора. Тоже самое наблюдается для численных литералов, уже обсуждалось: http://rsdn.ru/forum/flame.comp/3782092.1.aspx
Без такой оптимизации мы бы имели проблему как в первых компиляторах С++, поддерживающих шаблоны — очень большой бинарник. А тут имеет место "склейка" идентичных участков кода, поэтому готовый бинарник, порождаемый MSVC порой более чем в 2-3 раза меньше, чем порождаемый gcc.
Здравствуйте, vdimas, Вы писали:
V>Здравствуйте, nen777w, Вы писали:
N>>Такая проблема. N>>есть совершенно два разных cpp файла в которых в namespace определена одна и та же структура:
V>Ну так что пугает? Пользовательский конструктор у них одинаковый.
Тут не пугает, тут бага.
твой пример это оптимизация, которая не влияет на семантику.
А в случае автора — баг, который меняет семантику(ожидаемый результат)
Здравствуйте, IROV.., Вы писали:
IRO>Вопрос такой, разве тяжело давать варнинг/еррор в линкере когда он находит два определения?
Есть такая вещь как инстанциация шаблонов. Например, в разных единицах трансляции несколько раз инстанцируется std::max<int>(). Задача линкера, уже ничего не знающего о шаблонах, дать выжить только одной инстанциации в конечном исполняемом файле. Думаю, поэтому затруднительно выдавать предупреждение в каких-то специфичных случаях: не очень ясно, как можно быстро проверить эквивалентность функций. Впрочем, как это сделать не быстро, тоже не ясно .
Здравствуйте, 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.
Здравствуйте, Dmi3S, Вы писали:
DS>Здравствуйте, IROV.., Вы писали:
IRO>>Вопрос такой, разве тяжело давать варнинг/еррор в линкере когда он находит два определения?
DS>Есть такая вещь как инстанциация шаблонов. Например, в разных единицах трансляции несколько раз инстанцируется std::max<int>(). Задача линкера, уже ничего не знающего о шаблонах, дать выжить только одной инстанциации в конечном исполняемом файле. Думаю, поэтому затруднительно выдавать предупреждение в каких-то специфичных случаях: не очень ясно, как можно быстро проверить эквивалентность функций. Впрочем, как это сделать не быстро, тоже не ясно .
с функциями проблем никогда небыло, были проблемы с методами
Здравствуйте, IROV.., Вы писали:
IRO>Здравствуйте, Dmi3S, Вы писали:
DS>>Здравствуйте, IROV.., Вы писали:
IRO>>>Вопрос такой, разве тяжело давать варнинг/еррор в линкере когда он находит два определения?
DS>>Есть такая вещь как инстанциация шаблонов. Например, в разных единицах трансляции несколько раз инстанцируется std::max<int>(). Задача линкера, уже ничего не знающего о шаблонах, дать выжить только одной инстанциации в конечном исполняемом файле. Думаю, поэтому затруднительно выдавать предупреждение в каких-то специфичных случаях: не очень ясно, как можно быстро проверить эквивалентность функций. Впрочем, как это сделать не быстро, тоже не ясно .
IRO>с функциями проблем никогда небыло, были проблемы с методами
А есть разница между функциями и методами на стадии линковки?
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.
Здравствуйте, Dmi3S, Вы писали:
DS>Здравствуйте, IROV.., Вы писали:
IRO>>Вопрос такой, разве тяжело давать варнинг/еррор в линкере когда он находит два определения?
DS>Есть такая вещь как инстанциация шаблонов. Например, в разных единицах трансляции несколько раз инстанцируется std::max<int>(). Задача линкера, уже ничего не знающего о шаблонах, дать выжить только одной инстанциации в конечном исполняемом файле. Думаю, поэтому затруднительно выдавать предупреждение в каких-то специфичных случаях: не очень ясно, как можно быстро проверить эквивалентность функций. Впрочем, как это сделать не быстро, тоже не ясно .
предположительно это могли бы быть подсказки от компилятора, ему то об этом известно всё, хотя может Я не могу охватить всех специфических случаев.
Маленькое уточнение. Ты все правильно говоришь, но, возможно, не совсем точно — при чтении твоих постов может сложиться неверное мнение, будто бы все сущности, определенные в анонимных пространствах имен, автоматом получают внутреннее связывание. В анонимных пространствах имен действуют те же правила, что и в обычных — константы по умолчанию получают внутреннее связывание, функции, переменные и классы — внешнее. Только сами пространства имен изолированы от внешнего мира.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, nen777w, Вы писали:
N>предположительно это могли бы быть подсказки от компилятора, ему то об этом известно всё, хотя может Я не могу охватить всех специфических случаев.
Компилятору известно далеко не все, а только единица трансляции. Да и какие "подсказки" ему давать линкеру, у которого на входе уже действительно все, даже с излишком?