Неявное объявление функций независимо от заголовка include и ifndef

У меня есть известные ошибки:

implicit declaration of function 'STLINKReadSytemCalls' [-Wimplicit-function-declaration]
implicit declaration of function 'printf' [-Wimplicit-function-declaration]
incompatible implicit declaration of built-in function 'printf'

И Eclipse (точнее, Atollic TrueStudio) добавил:

include '<stdio.h>' or provide a declaration of 'printf'

Читая миллиарды сообщений о том, как решить эту проблему на SO, кажется, что эти проблемы могут быть вызваны четырьмя проблемами:

  • Функции определены после main;
  • Необходимые заголовки для использования функции включены
  • #ifndef, #define а также #endifне правильно обернуть файлы заголовков

Я нашел сообщение, в котором кто-то, кажется, имел эту ошибку и сказал после исправления, что проблема была в Eclipse. Хотя не могу найти тему, но его решение не сработало для меня. Это было что-то вроде щелчка по функции, источник -> добавить включает.

main.c

int main(void) {

    if (STLINKReadSytemCalls() == 1)
        printf("Error in system calls.\n");
    return 0;
}

fileProcessing.c

#include "../header/fileProcessing.h"

int STLINKReadSytemCalls(void) {

    // mainly system calls
}

fileProcessing.h

#ifndef FILEPROCESSING_H_
#define FILEPROCESSING_H_

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int STLINKReadSytemCalls(void);

#endif /* FILEPROCESSING_H_ */

Самым запутанным является то, что код действительно работает. У меня есть следующий вывод:

STM32 ST-LINK CLI v3.0.0.0
STM32 ST-LINK Command Line Interface

No ST-LINK detected
Unable to connect to ST-LINK!
Error in system calls.

Все вроде бы нормально, но компилятор все кричит. Я добавлю тело функции, если это необходимо, но я нигде не видел никаких подсказок, говорящих о том, что тело функции может вызвать ошибку включения. Я, должно быть, упускаю что-то настолько очевидное, что я пойду в себя, как никто, когда я это увижу; но я уже провел часы, и моя надежда, что это очевидно, становится все тоньше.

Да, и вчера с тем же путём включения и той же сборкой каталогов все работало отлично. Я действительно не знаю, что изменилось с тех пор.

2 ответа

Решение

Как вы представили, ваш main.c содержит вызовы двух функций, которые не имеют встроенного объявления: STLINKReadSytemCalls() а также printf(), Это соотносится с предупреждениями (а не с ошибками), генерируемыми компилятором, и только код, который вы представили, может объяснить эти предупреждения.

На этом этапе я подчеркиваю, что

  1. Проблема заключается в том, что я только что описал: отсутствие объявлений функций внутри области в момент вызова этих функций. Ваши "четыре проблемы [которые] могут вызвать эти ошибки" (только три фактически представлены) описывают различные конкретные пути, с помощью которых такие проблемы иногда возникают; ни одна из них сама по себе не является проблемой.

  2. Компилятор выдает предупреждения, а не ошибки. Это означает, что он принимает код, но не может быть уверен, что с ним все сделали правильно. В частности, он полагается на количество и тип аргументов, чтобы угадать списки аргументов, и предполагает, что функции возвращают int, Это небезопасно, но если вам повезет, это может сработать или, по крайней мере, сработает.

Учитывая, что проблема заключается в отсутствии объявлений функций, решение, очевидно, состоит в том, чтобы гарантировать, что все необходимые объявления предоставлены, и что они находятся в области действия, на которую ссылаются эти функции. Для функций, определенных не в том же источнике C, обычным решением является #include заголовочный файл или файлы, содержащие необходимые объявления. Предположим, что рассматриваемые заголовки написаны надлежащим образом (стандартная библиотека, а внутренняя представленная вами) - это все, что нужно сделать.

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

#include <stdio.h>
#include "../header/fileProcessing.h"

в начале main.cкак и предполагал @unwind. Этого изменения достаточно, чтобы удовлетворить мой компилятор.

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


Кроме того, я добавляю, что мне немного странно (но не неправильно), что ваш fileProcessing.h#includeстандарт stdio.h, stdlib.h, а также string.h Заголовки, даже если они не зависят ни от одного из них. Как правило, я настоятельно рекомендую, чтобы каждый исходный файл, включая заголовочные файлы, #include все заголовки требуются для функций, которые они используют напрямую, но не для других. В поддержку этого, все заголовки должны также иметь надлежащие средства защиты от множественного включения, как и заголовок, который вы фактически представляете.

Таким образом, я бы переписал fileProcessing.h вот так:

#ifndef FILEPROCESSING_H_
#define FILEPROCESSING_H_

int STLINKReadSytemCalls(void);

#endif /* FILEPROCESSING_H_ */

... и пусть другие файлы обрабатывают #includeиспользование любого или всех трех вышеупомянутых стандартных библиотечных заголовков по мере необходимости.

Вы не показываете, что ваш main.c файл имеет два довольно очевидных

#include <stdio.h>
#include "../header/fileProcessing.h"

линии, это специально? В противном случае это ответ, я думаю.

Возможно повторное использование FILEPROCESSING_H_ symboh. Может случиться с копией-вставкой.h

Другие вопросы по тегам