Вполне спокойно обучаем школьников на Си. Не скажу, что те же указатели всегда сходу даются, но и сильно больших проблем нет. Опять же, это про тех школьников, которые сами хотят.
Я бы сказал так, inline был для того, чтобы код функции напрямую подставлять в код вызывающей функции. А вот должна ли она при этом оставаться в бинарнике мне не очень очевидно (я вообще зарекся использовать это слово вместе со словом оптимизация =) ).
ооо, прикольно, об этом я не знал. То есть тут ещё и разное поведение в дебаге и релизе… В пример добавлю.
Для остальных: при оптимизации компилятор может честно заинлайнить эти функции и вообще не добавить эту функцию в таблицу символов.
Он это может сделать, видимо, потому-что несколько inline функций с разными реализациями — это Undefined behavior (не проверял, это мое предположение), а компилятор считает, что UB не существует => функции все одинаковые => если получится заинлайнить, то можно вообще функцию выбросить.
Для полноты картины можно также поговорить о слабой связи, ключевое слово inline. Если применять этот вид связи можно также обходить One Definition Rule (например писать реализации функций в хедере), как и в случае со static. Но механизм тут другой.
Когда используешь static, символы помечаются как внутрение, и One Definition Rule не нарушается. При inline символы остаются внешними (видны всем), но когда линковщик видит несколько одинаковых слабых символов, он оставляет только один из них, а остальные отбрасывает (как именно не стандартизированно, но 99%, что оставит тот, что увидел первым).
Тут есть небольшой плюс в том, что в бинарник попадет только один экземпляр кода, а не N (размер бинарника меньше). Однако с этим нужно быть очень осторожным. Вы вполне можете случайно (ну или специально) сделать несколько реализаций inline функций с одинаковым именем. Тогда программа будет работать немного странно =) Вот тут я набросал такой пример, где вывод программы зависит от того, в каком порядке передавать линкеру object файлы.
Ну и напоследок — все шаблонные функции обладают слабым связыванием.
Тут такая же ситуация, как с с++ раньше. Чтобы писать на нем, нужно внимательно следить за памятью, выделять, правильно освобождать, следить за всеми редкими случаями. Это очень тяжело, количество ошибок при написании было огромное.
Можно решать это улучшением стимула — отбором лучших сотрудников, повышения зарплаты, ответственности. Многие так и поступали. А можно изменить метод — сделать новый язык со сборкой мусора, или тем кто хочет остаться на с++ сделать умные указатели.
Если можно изменить методику так, чтобы человеческий фактор вообще выпал из рассмотрения (ну по крайней мере стал значительно меньше) — то это практически всегда более правильный путь.
А что с производительностью? Мне тут сказали, что некоторое время назад все было очень плохо.
Бегло посмотрел документацию, сильно смутило в faq
«computing branch names and colors (i.e. if the branch is dirty or not), can be a pretty slow operation. This is bad news because xonsh can try to compute these each time it formats the $PROMPT»
То есть я правильно понимаю, что он не может в многопоточность?
Ну вот. Теперь у вас есть нормально поставленное утверждение. Теперь продемонстрируйте для первого множества такую функцию f и докажите, что для второго такого f нет. Потому-что ваши словесные рассуждения совершенно непонятны.
Вот это меня совсем убило *сова.jpg*
Очевидно, что: 2 + 2 + 2 = 3 + 3 и 2 + 2 > 3, 2 < 3. Таким образом, пары чисел распределены следующим образом:
К тому же в вашем примере для первого множества отсутствуют, например, пара чисел (0, 2) Спрашивается почему?
Как ехидно говорил мой препод по матану: «Если вам это кажется очевидно, то для вас не будет никаких проблем это доказать».
Я правильно понимаю, что под порядком вы понимаете это.
Для мн-ва A = {a} задан порядок если существует биекция А <-> N (обозначим такие пары a_n) и функция f: A -> A, которая для каждого a_n вычисляет a_{n+1}
Иными словами если множество счетно и по элементу n можно однозначно определить эл-т n+1?
Или вы также требуете, чтобы f вычислялась за константу?
В таком виде совершенно не понятно что вы подразумеваете под «упорядочить множество {f(n, m)|n, m in N}».
То, как пишете вы: «способ найти следующую пару чисел n и m, зная предыдущую.» — элементарно и, вообще говоря, не зависит от функции, которую вы к этим числам применяете. Очевидно, вы имеете в виду что-то другое.
И да.
«простата какого-нибудь числа напрямую зависит от, например, какого-то знака после запятой»
Знаю, что такое нужно в личку. Но тут не удержался xD
А вообще меня самого в детстве учили виму, мне он нравился, но со временем я пересел на нормальные редакторы =) Но в последние года, я как-то начал включать вим плагин везде где можно: браузеры, IDE, файл менеджеры. Да и в самом виме провожу куда больше времени.
ps. Вы забыли написать, что на самом хабре jk переходят между постами =)
Нет. Инициализация по-умолчанию и отсутствие инициализации — принципиально разные вещи. Вот пример.
При конструировании Base вызывается foo, которая в свою очередь (если бы вызывалась foo из Derived) вызывает функцию класса A. При конструктор A ещё не был вызван. И как бы вы ловили такое? Тем более что вызов foo вполне мог бы появится внезапно для автора Derived.
Заголовок спойлера
struct A{
A(){
// some important work
}
void do_work(){
// need internal initialized vars
}
};
struct Base{
Base(){
foo();
}
virtual void foo() { }
};
struct Derived : Base{
Derived() = default;
virtual void foo() override {
a.do_work();
}
private:
A a;
};
int main(){
Derived derived;
}
Хм, да, спасибо, я действительно поспешил (да ещё и сформулировал коряво).
Однако вы не согласны, что это некие вырожденные примеры? А вот например ловить ошибку того, что я использую в своей функции переменную, у которой не сработал конструктор — гораздо больший гемор. Причем смотреть нужно на все переменные нашего класса во всех виртуальных функциях.
Кстати, вы похоже смотрели на другие языки. А как там решают данную проблему?
В с++ есть очень важная гарантия — методы класса не могут быть вызваны перед конструктором и после деструктора. Виртуальные методы в конструкторе/деструкторе родителя эту гарантию нарушает. И я, например, хочу эту гарантию гораздо больше, чем решить вашу конкретную проблему чуть более элегантным (как вам кажется) способом.
Для остальных: при оптимизации компилятор может честно заинлайнить эти функции и вообще не добавить эту функцию в таблицу символов.
Он это может сделать, видимо, потому-что несколько inline функций с разными реализациями — это Undefined behavior (не проверял, это мое предположение), а компилятор считает, что UB не существует => функции все одинаковые => если получится заинлайнить, то можно вообще функцию выбросить.
Когда используешь static, символы помечаются как внутрение, и One Definition Rule не нарушается. При inline символы остаются внешними (видны всем), но когда линковщик видит несколько одинаковых слабых символов, он оставляет только один из них, а остальные отбрасывает (как именно не стандартизированно, но 99%, что оставит тот, что увидел первым).
Тут есть небольшой плюс в том, что в бинарник попадет только один экземпляр кода, а не N (размер бинарника меньше). Однако с этим нужно быть очень осторожным. Вы вполне можете случайно (ну или специально) сделать несколько реализаций inline функций с одинаковым именем. Тогда программа будет работать немного странно =) Вот тут я набросал такой пример, где вывод программы зависит от того, в каком порядке передавать линкеру object файлы.
Ну и напоследок — все шаблонные функции обладают слабым связыванием.
ps. Мы в ЛШЮП такой фигни не делаем =)
Можно решать это улучшением стимула — отбором лучших сотрудников, повышения зарплаты, ответственности. Многие так и поступали. А можно изменить метод — сделать новый язык со сборкой мусора, или тем кто хочет остаться на с++ сделать умные указатели.
Если можно изменить методику так, чтобы человеческий фактор вообще выпал из рассмотрения (ну по крайней мере стал значительно меньше) — то это практически всегда более правильный путь.
Бегло посмотрел документацию, сильно смутило в faq
«computing branch names and colors (i.e. if the branch is dirty or not), can be a pretty slow operation. This is bad news because xonsh can try to compute these each time it formats the $PROMPT»
То есть я правильно понимаю, что он не может в многопоточность?
proninyaroslav.gitbooks.io/linux-insides-ru/content/Booting/linux-bootstrap-1.html
Может вам понравится.
Вот это меня совсем убило *сова.jpg*
К тому же в вашем примере для первого множества отсутствуют, например, пара чисел (0, 2) Спрашивается почему?
Я правильно понимаю, что под порядком вы понимаете это.
Для мн-ва A = {a} задан порядок если существует биекция А <-> N (обозначим такие пары a_n) и функция f: A -> A, которая для каждого a_n вычисляет a_{n+1}
Иными словами если множество счетно и по элементу n можно однозначно определить эл-т n+1?
Или вы также требуете, чтобы f вычислялась за константу?
То, как пишете вы: «способ найти следующую пару чисел n и m, зная предыдущую.» — элементарно и, вообще говоря, не зависит от функции, которую вы к этим числам применяете. Очевидно, вы имеете в виду что-то другое.
И да.
«простата какого-нибудь числа напрямую зависит от, например, какого-то знака после запятой»
Знаю, что такое нужно в личку. Но тут не удержался xD
А вообще меня самого в детстве учили виму, мне он нравился, но со временем я пересел на нормальные редакторы =) Но в последние года, я как-то начал включать вим плагин везде где можно: браузеры, IDE, файл менеджеры. Да и в самом виме провожу куда больше времени.
ps. Вы забыли написать, что на самом хабре jk переходят между постами =)
При конструировании Base вызывается foo, которая в свою очередь (если бы вызывалась foo из Derived) вызывает функцию класса A. При конструктор A ещё не был вызван. И как бы вы ловили такое? Тем более что вызов foo вполне мог бы появится внезапно для автора Derived.
Однако вы не согласны, что это некие вырожденные примеры? А вот например ловить ошибку того, что я использую в своей функции переменную, у которой не сработал конструктор — гораздо больший гемор. Причем смотреть нужно на все переменные нашего класса во всех виртуальных функциях.
Кстати, вы похоже смотрели на другие языки. А как там решают данную проблему?