= {}) {}
inline void foo() {
bar();
}
// test1.cpp
#incldue <test.hpp>
// test2.cpp
#incldue <test.hpp>
А тут не будет нарушения ODR?
хороший вопрос) у меня локально сейчас нет компилятор 20го, а на годболт не особо удобно всё это смотреть для кучи файлов (
не должно быть http://eel.is/c++draft/basic.def.odr#13.8
да, есть мнение что всё ок, типа когда будут компилировать foo там инстанциируют какую-то очередную версию bar и она будет дёргаться во всех TU
На практике получается, что у нас два разных bar в двух разных TU. А вот определение функции foo, обращающейся к bar одно. Ставлю на то, что взорвётся. Я почти уверен, что весь вопрос можно свести к следующему примеру и я почти уверен, что он взорвётся: // test.hpp static void bar() {} inline void foo() { bar(); } // test1.cpp #incldue <test.hpp> // test2.cpp #incldue <test.hpp>
Я думаю, что для нас имеют значение https://eel.is/c++draft/basic.def.odr#13.10 https://eel.is/c++draft/basic.def.odr#14.sentence-5 Благодаря этому, если я правильно распарсил текст стандарта, у нас в разных TU получаются разные типы у S<>. А соответственно, и у функций, принимающих эти типы. Это значит, что foo в разных TU внутри содержит вызовы разных функций
И типа эта проблема будет в любой функции, которая лямбдой параметризуется?
И у нас получается если использовать что-то такое template<typename T, typename = decltype([]{})> struct SType { SType(T t): t_{std::move(t)} {} operator T() { return t_; } T t_; }; using S1 = SType<std::string>; using S2 = SType<std::string>; То функции, которые принимают S1 и S2 тоже условно статическими становятся и можно вылететь в такой же ODR violation?
Я думаю, что да. Даже если внутри inline функции просто фигурирует S1 или S2, я бы не надеялся на то, что ноги уцелеют
не то чтобы разных на самом деле, скорее двух копий одной и той же функции
Нет, это именно что две функции (перегрузки?) разных типов, если я верно интерпретирую стандарт, у нас будет void bar(S<unique_type_from_first_tu>) и void bar(S<unique_type_from_second_tu>) и foo вызывает в одном TU одну из них, а во втором другую, что является явным ODR violation
это две одинаковые функции тем не менее, которые отличаются значением типа, там к слову на SO про это написано
>> две одинаковые функции тем не менее, которые отличаются значением типа Можно подробнее? Я не уверен, что понимаю терминологию И что значит "две одинаковые функции", если в стандарте в note упомянуто, что S<> и S<> can result in the different declarations having distinct types >> там к слову на SO про это написано И всё же, там про другой пример написано К счастью, у нас уже есть @r_mustang, который наступил на обсуждаемые нами грабли – у него взорвалось на границе с dll, нам не обязательно топтаться по граблям вслед за ним
как я уже сказал выше речь была не про стандарт, а про рассуждения, там функции отличаются фактически типом, который никак не используется, т.е. тело функции от него никак не зависит. С точки зрения стандарта это не ок, но по факту тут это ни на что не влияет, у нас просто получается две одинаковые функции которые отличаются замангленым именем, в итоге компилятор выберет любое определение которое ему понравится. Но это и правда просто рассуждения) так скорее всего будет но гарантии такой никто не даёт естественно, так что так лучше просто не писать
Ну я думал про вариант когда это может прострелить ноги это только когда ты будешь пытаться сохранять адрес bar в разных TU. Например, в одном случае foo может заинлайниться и сохранится bar из текущего TU, в другом нет и т.п.
Обсуждают сегодня