inline

Тема в разделе "Микроконтроллеры AVR", создана пользователем parovoZZ, 6 янв 2019.

  1. Asper Daffy

    Asper Daffy Гуру

    И совершенно напрасно.
    Так я же объяснил!

    Компилируются два файла. В моём примере: kaka.ino и stupid.cpp. Каждый компилируется в свой объектник. В первом коде функция stupid() размещается только в объектнике "stupid", а из объектника "kaka" она только вызывается. А во втором коде, функция "stupid" дублируется в обоих объектниках - т.е. в каждом своя копия этой функции, и в каждом файле вызывается своя копия. Вот потому итоговый файл (получающейся после объединения объектников), во втором случае больше - на размер этой самой продублированной функции.
     
    DetSimen нравится это.
  2. SergeiL

    SergeiL Гуру

    Так вроде вопрос был в другом:
    1 вариант - это несколько отдельных .c-шных файлов, которые собираются в один.
    2 вариант - это один .c-шный файл и все остальное в .h-нике, и тоже собирается в один.
    Не думаю, что будет разница по размеру кода.
     
  3. Asper Daffy

    Asper Daffy Гуру

    Я понимал вопрос по другому. Общие для разных С-файлов функции держим в отдельном(ых) С-файле(ах), или в include-файле, который включаем во все С-файлы, где эти функции используются. Второй вариант - разбазаривание памяти.
     
  4. SergeiL

    SergeiL Гуру

    А компилятор съест? Не будет редефинишена?
     
  5. Asper Daffy

    Asper Daffy Гуру

    Ну, компилятору-то пофиг - он имеет дело только с одним файлом и понятия не имеет о существовании других. Что до линкера, так я писал в том посте при каких условиях будет двойное определение, а при каких - не будет, почитайте. Да и примеры мои вполне рабочие, если что.
     
  6. SergeiL

    SergeiL Гуру

    Я под компилятором подразумевал весь процесс, включая сборку.
    Если в каждый си файл проекта пихать один и тот же инклудник с кодом функции (не определением, а кодом), и без #ifndef - #endif, то линкер 100% ругнется на редефинишен!
     
  7. DetSimen

    DetSimen Гуру

    тогда спасёть #pragma once
     
  8. SergeiL

    SergeiL Гуру

    Ну по поводу #pragma я уже спрашивал здесь
    Никто не ответил :)
     
  9. DetSimen

    DetSimen Гуру

    ну дак там другие прагмы, на них моя компетенция не распространяеца. Вернее, не на все
     
  10. Asper Daffy

    Asper Daffy Гуру

    А если с #ifndef - #endif, то тоже ругнётся, ничуть не хуже. Чем тут может помочь "#ifndef - #endif", когда их разбирает компилятор, который вообще не знает о существовании других .CPP файлов? Так в каждый объектник и вставит за милую душу. Можете попробовать.

    Как делать, чтобы не ругался, я Вам писал в посте #14 не хочу повторяться по сто раз. И, ещё раз - мои примеры рабочие, а там это делается безо всяких "#ifndef - #endif". Запустите, наконец, и убедитесь.
     
    KindMan и DetSimen нравится это.
  11. parovoZZ

    parovoZZ Гуру

    хотел написать, что я всегда так делаю, но тут вспомнил, что студия по умолчанию в шаблоне эти строчки содержит.
    ну так вы оба правы.

    ага. main.c и куча заголовочников. Ну а смысл держать и заголовочник и *.с файл?
    А почему? Компилятор разве из заголовочника не создаст единый файл?
     
  12. DetSimen

    DetSimen Гуру

    да, точно. once тут тоже не поможет
     
  13. SergeiL

    SergeiL Гуру

    Два кода приведенные в Вашем сообщении неравноценные, отличаются на те самые 172 байта или функцию:
    Код (C++):
    nt stupid(void) {
        Serial.begin(9600);
        long i = 0;
        for (; i < 100; i++) {
            Serial.write(i);
        }
        for (; i < 200; i++) {
            Serial.write(i);
        }
        for (; i < 300; i++) {
            Serial.write(i);
        }
        for (; i < 100500; i++) {
            Serial.write(i);
        }
        return Serial.read();
    }
     
  14. Asper Daffy

    Asper Daffy Гуру

    Это функция есть в обоих кодах. В одном коде она в .h файле, а в другом - в .cpp - та же самая функция.

    С какого перепугу? Сам по себе заголовочный файл вообще не компилируется. Заголовочный файл вставляется в то место, где стоит include и всё. Компилируется тот файл в котором стоит #include.

    В общем, мужики, Вы извините, но мне надоело. Как мог я объяснил, лучше не могу. Будем считать, что не сумел объяснить, и закончим на этом.
     
  15. SergeiL

    SergeiL Гуру

    Согласен.
    Я в принципе не понял зачем Вам в первом варианте stupid.cpp, у Вас же все в .h, об этом и говорили.
    Уберите из проекта stupid.cpp, и код будет такой же по размеру.
    ОБ ЭТОМ я и говорил с самого начала!

    Да, тоже достало, Тоже пытался объяснить как мог!
     
  16. parovoZZ

    parovoZZ Гуру

    да, да, ты прав)) Мы же сейчас исключительно про inline static функции, правда? Только я не понимаю, почему пойдёт разбазаривание памяти, если для ОДНОКРАТНО вызываемой функции мы убираем, как минимум, CALL и RET? Для многократно вызываемой простой функции
    Код (C++):
    return GPIOR0;
    ожидаемо случится тоже самое. Где разбазаривание памяти?
     
    SergeiL нравится это.
  17. SergeiL

    SergeiL Гуру

    Будет даже меньше, еще уберется закидывание и скидывание со стека или регистров.
     
    Последнее редактирование: 9 янв 2019
  18. parovoZZ

    parovoZZ Гуру

    так а реально будет работа со стеком для такой функции
    Код (C++):
    void my_function (void)
    {
    .....
    }
    ?
     
  19. Asper Daffy

    Asper Daffy Гуру

    Нет, нет, я уже сказал, давайте завязывать - это разговор слепого с глухим - "мыло и мочало, мы начнём с начала". В посте №14 отвечал на Ваш пост, где Вы писали "ВСЕ" функции. Я там (в посте 14) явно написал "без инлайн". И именно при этих условиях я писал о перерасходе памяти. А Вы опять-двадцать пять - "исключительно про inline static функции"!

    Из пустого в порожнее одно и тоже, давайте завязывать. Если у Вас есть конкретный вопрос задайте, только чётко, ничего не скрывая и не держа в уме. Я отвечу. А так - мне надоело.

    И да, разумеется - однократно используемая инлайн-функция ни к какому перерасходу памяти не ведёт, говорить не о чем.
     
  20. parovoZZ

    parovoZZ Гуру

    Под "все" я подразумевал не "все inline", а вообще все, если нет приватных. Если inline функции писать в заголовке, а остальные в *.с - тогда первые логичнее макросами определить. Макросы в заголовочнике, кмк, нормальное явление, а определение функции - нет.