Приблизительно так же на собесах объяснял, что такое классы и ни разу не проходил. Это хорошо знать для себя, на собесах лучше говорить как можно проще, лучше вообще опуститься до объяснения букв SOLID.
Тайминг ролика 18:20: при объявлении указателя на функцию с пустым списком аргументов и его вызове с разным количеством аргументов - все аргументы, в соответствии с соглашением о вызове функции, будут либо неявно приведены к типу int через стэк, либо помещены в несоответствующие регистры, а значит если такому указателю назначить адрес функции с аргументом типа float, то вы получите мусор в аргументе внутри самой функции. Это UB. Такой же эффект бывает при вызове любой написанной функции в месте, где не видно ни её, тело ни прототип. Из той же серии, можно объявить функцию без типа возвращаемого значения и это не будет ошибкой, лишь предупреждением компилятора о неявном указании int, как типа возвращаемого значения по умолчанию. Подобный полиморфизм сработает корректно, когда у аргументов указателя на функцию указаны типы в соответствии с аргументами функции с наибольшим числом аргументов, причем порядок типизации не может быть нарушен: void f1(float a,int b,void *c){...} void f2(float a,int b){...} void f3(float a){...} void (*f)(float a,int b,void *c); f=f1; f(1.1,1,0x111); f=f2; f(2.2,2,0x222); f=f2; f(3.3,3,0x333);
Мощно! 🔥Это ж даёт сразу все фишки современных языков: интерфейсы, джэнэрики, колл-бэки, а с ними и всё функциональное программирование: zip, map и тд. Но вопрос: а почему Сишники об этом столько лет молчали? Зачем навыдумывали ужасные макросы и пре-компиляторы? Большое спасибо за видео 🙏💗
И да и нет, но скорее нет, чем да. Для перечисленных выше концепций у Си нет многих фундаментальных возможностей. Интерфейсы невозможны в Си, можно реализовать только их кривое подобие, самому vtable манажить, имитировать рантайм диспатч и т.п... такое себе. Дженерики и _Generic - это разные вещи, в Си дженериков просто нет, можно их макросами имитировать, но это все равно будет сложно дженериками назвать в полноценном их понимании. Кол-беки да, но только простую их форму, а так без капчуринга, автоматического управления памятью - ну такое себе, ни о каких замыканиях и речи нет. Но в этом и есть фишка Си, что он заставляет тебя подумать, а как сделать твой код проще, и обойтись без всех этих продвинутых концепций, и очень часто так и получается, реально прочищает мозги))
Если имя не потеряли, то можно: ведь имя как раз и содержит адрес (хотя имя - это и не указатель, но похоже). Если имя тоже потеряли - становится интересно!
Топовый контент, огромное спасибо Вам!
Приблизительно так же на собесах объяснял, что такое классы и ни разу не проходил. Это хорошо знать для себя, на собесах лучше говорить как можно проще, лучше вообще опуститься до объяснения букв SOLID.
Вы, скорее всего, правы - просто знаете, тема собесов меня нисколько не занимает. Скорее тема реального понимания, желательно на кончиках пальцев.
Тайминг ролика 18:20: при объявлении указателя на функцию с пустым списком аргументов и его вызове с разным количеством аргументов - все аргументы, в соответствии с соглашением о вызове функции, будут либо неявно приведены к типу int через стэк, либо помещены в несоответствующие регистры, а значит если такому указателю назначить адрес функции с аргументом типа float, то вы получите мусор в аргументе внутри самой функции. Это UB.
Такой же эффект бывает при вызове любой написанной функции в месте, где не видно ни её, тело ни прототип.
Из той же серии, можно объявить функцию без типа возвращаемого значения и это не будет ошибкой, лишь предупреждением компилятора о неявном указании int, как типа возвращаемого значения по умолчанию.
Подобный полиморфизм сработает корректно, когда у аргументов указателя на функцию указаны типы в соответствии с аргументами функции с наибольшим числом аргументов, причем порядок типизации не может быть нарушен:
void f1(float a,int b,void *c){...}
void f2(float a,int b){...}
void f3(float a){...}
void (*f)(float a,int b,void *c);
f=f1; f(1.1,1,0x111);
f=f2; f(2.2,2,0x222);
f=f2; f(3.3,3,0x333);
Интересно, покопаюсь, спасибо.
@@olgapavlovaИ? Чем компилируем? Гнус неинтересен 😊 С новым годом! 🎄🎅🤡🎇
Очень интересно, спасибо
Мощно! 🔥Это ж даёт сразу все фишки современных языков: интерфейсы, джэнэрики, колл-бэки, а с ними и всё функциональное программирование: zip, map и тд. Но вопрос: а почему Сишники об этом столько лет молчали? Зачем навыдумывали ужасные макросы и пре-компиляторы? Большое спасибо за видео 🙏💗
Да суровые сишники вообще, похоже, неразговорчивые ребята :) Но в книжках всё вроде пишут спокойно, не скрывая.
И да и нет, но скорее нет, чем да. Для перечисленных выше концепций у Си нет многих фундаментальных возможностей. Интерфейсы невозможны в Си, можно реализовать только их кривое подобие, самому vtable манажить, имитировать рантайм диспатч и т.п... такое себе. Дженерики и _Generic - это разные вещи, в Си дженериков просто нет, можно их макросами имитировать, но это все равно будет сложно дженериками назвать в полноценном их понимании. Кол-беки да, но только простую их форму, а так без капчуринга, автоматического управления памятью - ну такое себе, ни о каких замыканиях и речи нет.
Но в этом и есть фишка Си, что он заставляет тебя подумать, а как сделать твой код проще, и обойтись без всех этих продвинутых концепций, и очень часто так и получается, реально прочищает мозги))
Класс!
А если я вдруг функцию потерял, можно её в памяти по имени найти? 😂 С новым годом! 😁
Если имя не потеряли, то можно: ведь имя как раз и содержит адрес (хотя имя - это и не указатель, но похоже).
Если имя тоже потеряли - становится интересно!
Ваше мнение про язык ZIG, пожалуйста
А и нету мнения, не трогала ещё :) Но обязательно потрогаю, спасибо!
@@olgapavlova для ютуба что нибудь запилите на ZIG и сравнить с С
получился питон😆🐍🐍?
Мы стремимся к тому, чтобы получился 1С :-)