LINUX.ORG.RU

implicit declaration of function, ЯННП

 


0

2

простой код, ничего сложного

#include <stdio.h>
#include <unistd.h>

int main() {
	while(printf("nanosleep happens\n")) {
		usleep(1000000);
	}
}
компилим
$ c89 nanosleep.c
$
окей. Компилим иначе
$ c99 nanosleep.c
nanosleep.c: In function ‘main’:
nanosleep.c:7:3: warning: implicit declaration of function ‘usleep’ [-Wimplicit-function-declaration]
   usleep(1000000);
   ^
$
Казалось бы, уже почти год работаю, а тут какая-то хрень ввела меня в ступор...

Не могу понять почему идет ругань на отсутствующее объявление нужной функции, я же подключил unistd.h. Что изменилось при смене стандарта?

★★★★★

(cpp <<q
#include <unistd.h>
q
 )|grep usleep
(cpp <<q
#include <unistd.h>
q
   )|grep __useconds_t |head -1

эээ 1000000 is unsigned int ?

различие по причине изменения в нюансках приведения типов числовых литералов?

qulinxao ★★☆
()

man открой

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       usleep():
           Since glibc 2.12:
               _BSD_SOURCE ||
                   (_XOPEN_SOURCE >= 500 ||
                       _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) &&
                   !(_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)
           Before glibc 2.12:
               _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от waker
gcc --version
gcc (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
reprimand ★★★★★
() автор топика

За правильное местоположение extern!


int
main(){
        #include <stdio.h>
        #include <unistd.h>
        if(printf("nanosleep happens\n")){
                usleep(1000000);
                main();
	}
}
qulinxao ★★☆
()
Последнее исправление: qulinxao (всего исправлений: 1)
Ответ на: комментарий от waker

не знаю, мб и не сломали

шлангом у меня тоже работает, правда, под другой системой

$ uname
FreeBSD
$ c99 nanosleep.c
$

reprimand ★★★★★
() автор топика
Ответ на: комментарий от reprimand

угу, причем даже понятно почему — из-за _BSD_SOURCE..

на линухе, видимо, можно пофиксить через -D_GNU_SOURCE

waker ★★★★★
()
Ответ на: комментарий от beastie

дык можидь с99 ригористичней в части того что с чего это тут uint32?

qulinxao ★★☆
()
Ответ на: комментарий от reprimand

Потому, что оно, скорей всего, само нужные флаги ставит. Но тут я далеко из окна высовываться не буду.

#if (defined __USE_XOPEN_EXTENDED && !defined __USE_XOPEN2K8) \
    || defined __USE_BSD
/* Set an alarm to go off (generating a SIGALRM signal) in VALUE
   microseconds.  If INTERVAL is nonzero, when the alarm goes off, the
   timer is reset to go off every INTERVAL microseconds thereafter.
   Returns the number of microseconds remaining before the alarm.  */
extern __useconds_t ualarm (__useconds_t __value, __useconds_t __interval)
     __THROW;

/* Sleep USECONDS microseconds, or until a signal arrives that is not blocked
   or ignored.

   This function is a cancellation point and therefore not marked with
   __THROW.  */
extern int usleep (__useconds_t __useconds);
#endif
beastie ★★★★★
()
Ответ на: комментарий от reprimand

Эта часть как раз намекает, что тебе надо _BSD_SOURCE или _XOPEN_SOURCE >= 500 или _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED задефайнить

SZT ★★★★★
()
Ответ на: комментарий от beastie

вот тебе нота из вышеобсужаемого мана

NOTES
       The type useconds_t is an unsigned integer type capable of holding integers in the range [0,1000000].  Programs will
       be more portable if they never mention this type explicitly

qulinxao ★★☆
()
Ответ на: комментарий от qulinxao

Квадратные скобки намекают, что значения 0 и 1000000 включены в диапазон. Но таки да, errval проверять надо. ;)

beastie ★★★★★
()
Ответ на: комментарий от qulinxao

1000000 == 0x000f4240 т.ч. это никак не может быть short, но это вполне может быть signed int32.

beastie ★★★★★
()
Ответ на: комментарий от reprimand

Conforming To

4.3BSD, POSIX.1-2001. POSIX.1-2001 declares this function obsolete; use nanosleep(2) instead. POSIX.1-2008 removes the specification of usleep().

Видимо поэтому. Объявляя *_SOURCE-макросами что у тебя за сорец, ты как бы going back in time, хотя сейчас твоей функции уже как бы нет.

arturpub ★★
()
Ответ на: комментарий от beastie

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

reprimand ★★★★★
() автор топика

что с89 и с99 на такой вариант? :


#include <stdio.h>
#include <unistd.h>

int main() {
	while(printf("nanosleep happens\n")) {
		usleep((unsigned int)1000000);
	}
}
qulinxao ★★☆
()
Ответ на: комментарий от arturpub

OSIX.1-2001 declares this function obsolete; use nanosleep(2) instead. POSIX.1-2008 removes the specification of usleep().

опа. Теперь я до конца понял где собака зарыта...

reprimand ★★★★★
() автор топика
Ответ на: комментарий от beastie

Кстати, BSD'шный ман тут лучше свёрстан:

     Some implementations of usleep() return an error if microseconds is
     greater than or equal to 1,000,000.  Portable applications should be
     written with this limitation in mind.

Сразу ясно, что <1000000.

beastie ★★★★★
()
Ответ на: комментарий от reprimand

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

arturpub ★★
()
Ответ на: комментарий от reprimand

Таки да, маны до конца читать надо. :D

PS: отмечай тему, как решённую

beastie ★★★★★
()
Ответ на: комментарий от reprimand

помнится, давно уже все стали юзать nanosleep. раньше в usleep были какие-то тараканы. сейчас уже не помню, но вроде они были связаны с таймерами, которые могли сбиваться, и иногда usleep клинило.

Iron_Bug ★★★★★
()
Ответ на: комментарий от reprimand

никогда не понимал вот этой части в манах к функциям, какая-то стена непонятного текста

Ну блин, написано же, «see feature_test_macros(7)», там всё подробно разжёвано.

theNamelessOne ★★★★★
()

Зачем тебе це? :-) Лол :-)

anonymous
()
$ gcc -std=c89 test.c
$ gcc -std=c89 test.c -Wall
test.c: In function ‘main’:
test.c:6:3: warning: implicit declaration of function ‘usleep’ [-Wimplicit-function-declaration]
   usleep(1000000);
   ^
test.c:8:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
$ man gcc
...
       -Wimplicit-function-declaration (C and Objective-C only)
           Give a warning whenever a function is used before being declared. In C99 mode (-std=c99
           or -std=gnu99), this warning is enabled by default and it is made into an error by
           -pedantic-errors. This warning is also enabled by -Wall.
...
kim-roader ★★
()
Последнее исправление: kim-roader (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.