warning: implicit declaration of function ‘kill’ [РЕШЕНО]
Добрый день!
Не знаю даже, где задать вопрос такой? Все, к кому обращался, не знают ответа.
Пишу код на Си (стандарт: ANSI C99 (ISO/IEC 9899:1999)) под Linux, но так же нужно чтобы он запускался и под BSD, QNX и другие POSIX-совместимые системы.
Вот кусок Makefile:
OUTPUT = engine LANGUAGE = -std=c99 OBJ = ./obj/ BIN = ./bin/ SRC = ./src/ LIB = INCLUDES = # For release #OPTIMIZATION = -O3 # For debug OPTIMIZATION = -O0 -g WARNINGLEVEL = -Wall CC = gcc CFLAGS += $(WARNINGLEVEL) CFLAGS += $(OPTIMIZATION) CFLAGS += $(LIB) CFLAGS += $(LANGUAGE) Далее таргеты
Т.е. видите, что я использую -std=c99.
Вот кусок кода в файле main.c:
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <stdbool.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <signal.h> Далее идёт код И на строке 457 вызывается функция kill
Обратите внимание на то, что файлы <sys/types.h>, <signal.h> подключены вначале файла, и <sys/types.h> включён раньше <signal.h> (если это имеет значение).
При компиляции, компилятор ругается:
./src/main.c:457: warning: implicit declaration of function ‘kill’
Т.е. он не видит kill, при этом исполняемый elf-файл собирается.
При запуске исполняемого файла kill отрабатывает нормально.
Читаем man:
$ man 2 kill
KILL(2) Linux Programmer's Manual KILL(2)
NAME
kill - send signal to a process
SYNOPSIS
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
kill(): _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE
Как видно, требуется подключение двух заголовочных файлов: <sys/types.h> и <signal.h>. В файле main.c, где вызывается kill, они подключены.
Но не работает! Компилятор ругается. Хотя всё линкуется и исполняется вполне корректно.
Теперь давайте посмотрим код в файле signal.h:
/* Send signal SIG to process number PID. If PID is zero, send SIG to all processes in the current process's process group. If PID is < -1, send SIG to all processes in process group - PID. */ #ifdef __USE_POSIX extern int kill (__pid_t __pid, int __sig) __THROW; #endif /* Use POSIX. */
Объявление находится под ifdef __USE_POSIX. Пробовал в файле main.c писать так:
#ifdef __USE_POSIX
printf("\n\nPOSIX USE\n\n");
#else
printf("\n\nPOSIX NOT USE\n\n");
#endif
Выводит: POSIX NOT USE
В чём же дело?
- Для комментирования войдите или зарегистрируйтесь

Хидеры проекта покажи :)
Хидеры проекта покажи :)
и посмотри что генерит cpp
Compute:
Bosch M2.8.1 -> custom Bosch M2.8.3 clone from Russia.
Speed about 260 km,Ram 2 pers.,HDD - 70 kg,210 FLOPS ;)
slepnoga написал(а): Хидеры
Не понял. Какие хедеры? Я же показал вроде:
Можно поподробнее? Какой cpp?
не понял. Какие хедеры? Я же
У тебя весь проект состоит из 1-го файла ?
DESCRIPTION The C preprocessor, often known as cpp, is a macro processor that is used automatically by the C compiler to transform your program before compilation. It is called a macro processor because it allows you to define macros, which are brief abbreviations for longer constructs. The C preprocessor is intended to be used only with C, C++, and Objective-C source code. In the past, it has been abused as a general text processor. It will choke on input which does not obey C's lexical rules. For example, apostrophes will be interpreted as the beginning of character constants, and cause errors. Also, you cannot rely on it preserving characteristics of the input which are not significant to C-family languages. If a Makefile is preprocessed, all the hard tabs will be removed, and the Makefile will not work. Having said that, you can often get away with using cpp on things which are not C. Other Algol-ish programming languages are often safe (Pascal, Ada, etc.) So is assembly, with caution. -traditional-cpp mode preserves more white space, and is otherwise more permissive. Many of the problems can be avoided by writing C or C++ style comments instead of nativeCompute:
Bosch M2.8.1 -> custom Bosch M2.8.3 clone from Russia.
Speed about 260 km,Ram 2 pers.,HDD - 70 kg,210 FLOPS ;)
Да какая разница какие хедеры
Да какая разница какие хедеры в других файлах?
В общем, разобрался! Всем спасибо!
Дополнительно
Хотелось бы добавить вот что:
когда вместо -std=c99 ставлю -std=gnu99, то ошибок не возникает, всё компилируется и линкуется без предупреждений.
При этом, если я использую -std=c99 у меня ругается на kill, но на open, read, write, fork, setsid, chdir, sysconf, unlink и другие функции, не входящие в стандарт ANSI C99, но входящие в стандарт POSIX не ругается и воспринимает их без предупреждений.
Кто-то может как-то прокомментировать эту ситуацию?
Возможно это связано с тем, что signal.h входит в стандарт ANSI C99 и ANSI C89, но в них не определена функция kill. А если мы используем стандарт GNU, то в этих файлах есть kill. Как вы думаете?
Надеюсь поможет
Судя по
это как-то завязано на спецификацию IEEE Std 1003.1...
UPD
А, это и есть спецификация POSIX
http://ru.wikipedia.org/wiki/POSIX
UPD2
Короче говоря, функция kill входит состав POSIX
А зачем, собственно
-std=c99?eegorov написал(а): Судя по
Ну что она (функция kill) входит в стандарт POSIX и другие стандарты (я уже написал в посте "Предположение") это понятно, конечно. Просто у меня то была проблема такая: функция, например, fork так же входит в стандарты POSIX и другие (SVr4, 4.3BSD, POSIX.1-2001), но на неё компилятор не ругается. А на kill ругается. Но теперь я понял почему.
В общем, всё дело в том, что она объявлена в одном и том же заголовочном файле, который описан в стандарте ANSI C.
В смысле зачем? Для указания стандарта, который использую.
Предположение
Пока писал и изучал проблему, додумался.
В общем так. Открываем стандарт: ISO/IEC 9899:1999 (WG14/N1124 Committee Draft - May 6, 2005 ISO/IEC 9899:TC2). Извините, уж что нашёл.
Читаем его. Параграф 7 определяет библиотеки, входящие в стандарт. Раздел 7.14 описывает что в стандарт входит библиотека для работы с сигналами, заголовочный файл которой signal.h.
Смотрим что входит в этот заголовочный файл: типы, макросы, функции.
Вот цитата из стандарта:
Функции всего две:
Функция kill не входит в стандарт ISO/IEC 9899:1999.
Но в Linux (и других POSIX-совместимых заголовочных файлах) она определена так же в файле signal.h. Но под #ifdef:
Т.е. функция kill находится в расширении стандарта, но не входит в сам стандарт ISO/IEC 9899:1999. Даже не так - функция kill определена в стандартах: SVr4, 4.3BSD, POSIX.1-2001 (man 2 kill). При этом она определена в том же файле signal.h, а не в отдельном файле. И когда в опции компилятора gcc ставится -std=gnu99, определяются несколько новых define и включается kill. А функции fork, read, write, sysconf, chdir и т.д. определены в отдельных файлах, поэтому опция компилятора -std=gnu99 или -std=c99 никак не влияет на это.
В общем, причина понятна. Просто надо включить расширение -std=gnu99 и тогда компиляция проходит без ошибок!
Просто надо включить
мдя, а просил -std=std99
насколько мне подсказывает мои старый маразматический моск int __sig есть __номер__ сигнала.
т.е для -std=std99 туда надо тупо обертку с int __sig == 9 - вот вам и kill.
Если уж совсем переносимо,т.е винды или наколенные системы, то можно чекать номер сигнала при сборке и дефайнить его
Compute:
Bosch M2.8.1 -> custom Bosch M2.8.3 clone from Russia.
Speed about 260 km,Ram 2 pers.,HDD - 70 kg,210 FLOPS ;)