Неявное объявление функций независимо от заголовка 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()
, Это соотносится с предупреждениями (а не с ошибками), генерируемыми компилятором, и только код, который вы представили, может объяснить эти предупреждения.
На этом этапе я подчеркиваю, что
Проблема заключается в том, что я только что описал: отсутствие объявлений функций внутри области в момент вызова этих функций. Ваши "четыре проблемы [которые] могут вызвать эти ошибки" (только три фактически представлены) описывают различные конкретные пути, с помощью которых такие проблемы иногда возникают; ни одна из них сама по себе не является проблемой.
Компилятор выдает предупреждения, а не ошибки. Это означает, что он принимает код, но не может быть уверен, что с ним все сделали правильно. В частности, он полагается на количество и тип аргументов, чтобы угадать списки аргументов, и предполагает, что функции возвращают
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