What Can I Use Besides usleep in a Modern POSIX Environment? - c

I'm fairly new to C but writing a small multithreaded application. I want to introduce a delay to a thread. I'd been using 'usleep' and the behavior is what I desire - but it generates warnings in C99.
implicit declaration of function ‘usleep’
It's only a warning, but it bothers me. I've Googled for an answer but all I could find was a while-loop / timer approach that seemed like it would be CPU intensive.
EDIT:
My includes are:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
And I'm invoking the compiler with:
c99 program.c -Wall -pedantic -W -lpthread
EDIT #2:
I've created a new file that contains:
#include <unistd.h>
int main(void) {
usleep(10);
}
And I still get the warning.
EDIT #3:
As suggested, I've updated the text of the question.

The problem is that you are using a standard C99 compiler, but you're trying to access POSIX extensions. To expose the POSIX extensions you should for example define _POSIX_C_SOURCE to 200809L (for the current standard). For example this program:
#include <time.h>
int main(void) {
struct timespec reqtime;
reqtime.tv_sec = 1;
reqtime.tv_nsec = 500000000;
nanosleep(&reqtime, NULL);
}
will compile correctly and wait for 1.5 seconds (1 second + 500000000 nanoseconds) with the following compilation command:
c99 main.c -D _POSIX_C_SOURCE=200809L
The _POSIX_C_SOURCE macro must be defined with an appropriate value for the POSIX extensions to be available.
Also the options -Wall, -pedantic and -W are not defined for the POSIX c99 command, those look more like gcc commands to me (if they work on your system then that's fine, just be aware that they are not portable to other POSIX systems).

You are probably on a modern POSIX system:
POSIX.1-2008 removes the specification of usleep().
On my system (linux) there is a detailed explanation of the macros that must be set to get that function back. But you should just follow the advice that zvrba already gave, use nanosleep instead.

From the manual page: This function is obsolete. Use nanosleep instead.

implicit declaration of function ‘usleep’
This warning usually means that you didn't #include the right header file, in this case unistd.h.

Did you have the #include <unistd.h> ?.
And you can use some of the similar methods instead: nanosleep() for nanoseconds and sleep() for seconds. Or another way could be using clock(), but i think this is more CPU wasting.

Related

usleep issue with unistd.h [duplicate]

I'm fairly new to C but writing a small multithreaded application. I want to introduce a delay to a thread. I'd been using 'usleep' and the behavior is what I desire - but it generates warnings in C99.
implicit declaration of function ‘usleep’
It's only a warning, but it bothers me. I've Googled for an answer but all I could find was a while-loop / timer approach that seemed like it would be CPU intensive.
EDIT:
My includes are:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
And I'm invoking the compiler with:
c99 program.c -Wall -pedantic -W -lpthread
EDIT #2:
I've created a new file that contains:
#include <unistd.h>
int main(void) {
usleep(10);
}
And I still get the warning.
EDIT #3:
As suggested, I've updated the text of the question.
The problem is that you are using a standard C99 compiler, but you're trying to access POSIX extensions. To expose the POSIX extensions you should for example define _POSIX_C_SOURCE to 200809L (for the current standard). For example this program:
#include <time.h>
int main(void) {
struct timespec reqtime;
reqtime.tv_sec = 1;
reqtime.tv_nsec = 500000000;
nanosleep(&reqtime, NULL);
}
will compile correctly and wait for 1.5 seconds (1 second + 500000000 nanoseconds) with the following compilation command:
c99 main.c -D _POSIX_C_SOURCE=200809L
The _POSIX_C_SOURCE macro must be defined with an appropriate value for the POSIX extensions to be available.
Also the options -Wall, -pedantic and -W are not defined for the POSIX c99 command, those look more like gcc commands to me (if they work on your system then that's fine, just be aware that they are not portable to other POSIX systems).
You are probably on a modern POSIX system:
POSIX.1-2008 removes the specification of usleep().
On my system (linux) there is a detailed explanation of the macros that must be set to get that function back. But you should just follow the advice that zvrba already gave, use nanosleep instead.
From the manual page: This function is obsolete. Use nanosleep instead.
implicit declaration of function ‘usleep’
This warning usually means that you didn't #include the right header file, in this case unistd.h.
Did you have the #include <unistd.h> ?.
And you can use some of the similar methods instead: nanosleep() for nanoseconds and sleep() for seconds. Or another way could be using clock(), but i think this is more CPU wasting.

clang linking error: undefined reference to 'qsort'

Despite the fact that i included '#include ' to my code, when i use built-in qsort function, clang gives me the error:
schedule.o: In function `chooseTicket':
schedule.c:(.text+0x16d): undefined reference to `qsort'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
start of the file (schedule.c) is like that:
#include "sched.h"
#include "schedproc.h"
#include <assert.h>
#include <minix/com.h>
#include <machine/archtypes.h>
#include <stdlib.h>
#include <lib.h>
#include <string.h>
#include <time.h>
and here is the function in which i used qsort built-in function
int chooseTicket(int* ticketList,int length,int totalTicket){
int randomValue;
int temp=0,prevTemp=0,selectedTicket=0,selectedIndex = 0;
time_t t;
struct schedproc *rmp;
int* sortedTicketList = malloc(length*sizeof(int));
memcpy(sortedTicketList,ticketList,length);
srandom((unsigned)time(&t));
randomValue = (random() % totalTicket);
qsort(sortedTicketList,length,sizeof(int),cmpFunc);//this line
note: Same errors also occured for 'rand()' and 'srand()' function and instead i have used 'random()' and 'srandom()', then the problem was solved. I don't understand despite the fact that 'rand()' and 'srand()' is generally accepted functions and header file contains these functions, why clang gives me linking errors while i am using 'rand()' and 'srand().
First, qsort is not a built-in, but part of the C standard library (formally, for hosted environments.)
Second, you need to learn that #include only allows access to the declarations of the functions in any given library. You need to link with the library, for your program to actually perform the call to the functionnality. Since you are getting a linker error here, no #include are going to help.
I guess you are writing a MINIX service, hence linking with libminc rather than with the full standard library ("libc"); in other words, this is a freestanding environment. And it happens qsort() is not in the restricted set of C functions included in libminc.
Either link with qsort.(c|o) specifically; or expand your own local version of libminc to include qsort(); or eat the whole cake and link with full libc, perhaps by adding DPADD+= ${LIBC}; LDADD+= -lc to the Makefile (I never tried to do that but it was supposed to work at some point, according to the code; it is not usual practice, so expect problems down the road.)

FreeBSD: Implicit declaration of getpagesize with _POSIX_C_SOURCE=200809L defined.

I am currently porting some OS related function of a software project from Linux to FreeBSD. Thereby, I recognized the following problem using getpagesize if _POSIX_C_SOURCE=200809Lis defined on FreeBSD 10.1.
I created a small test program
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int i = getpagesize();
return 0;
}
If I compile is using
cc test.c -o test
it compiles without any warnings. But if I define _POSIX_C_SOURCE=200809L (result of the proper POSIX definition of getline function which I need in other parts of the code) I get:
cc test.c -D_POSIX_C_SOURCE=200809L
test.c:5:10: warning: implicit declaration of function 'getpagesize' is invalid in C99 [-Wimplicit-function-declaration]
int i = getpagesize();
^
Although I included unistd.h as stated in the manpage of getpagesize. How can I make the code compiling without warnings with still defined _POSIX_C_SOURCE?
(1) The _POSIX_C_SOURCE is a wrong define. You need the _XOPEN_SOURCE. For example:
cc -D_XOPEN_SOURCE=700 test.c
or
cc -D_XOPEN_SOURCE=600 test.c
The 600 and 700 signify version of the Single Unix Specification (SUS for short, aka Open Group Specification, aka POSIX) your application expects from the system library. See here for the SUSv7.
(2) BUT. That might still not work, because the getpagesize() is a BSD-specific function, which actually might be hidden if you try to compile the file in the POSIX-compliance mode.
Normally you need nothing special to get access to the BSD functions on a BSD system, but portable way is to provide the _BSD_SOURCE define.
The more portable, POSIX-compliant way to get the page size is sysconf(_SC_PAGE_SIZE) function. FreeBSD man page.
P.S. Do not have a BSD at hand to test it.

vfork() implicit declaration

I working in C with vfork(). My program working fine, but I have warning about implicit declaration.
My code:
if(vfork()==0){
...
}
My warning is:
implicit declaration of function 'vfork' [-Wimplicit-function-declaration] if(vfork()==0){^
I include those:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
If I use fork() and not vfork() warning gone. Soo problem is only vfork() in my program.
I don't know what this mean or how I fix that.
You need to include these 2 headers:
#include <sys/types.h>
#include <unistd.h>
Also, add this line in the beginning of the program:
#define _BSD_SOURCE
If you already have the required include files, then, depending on your system version, you may need to define some feature test macros. Please see documentation for your system (man vfork on unix-like systems)
Adding onto Igor's answer, make sure you aren't compiling for C99. clang gives me the error "implicit declaration of function 'vfork' is invalid in C99", and removing -std=c99 from the arguments fixed the issue.

Difference between wait in stdlib.h and sys/wait

I'm pretty sure there's such question, but I can't find it :\ Anyway, here's the issue:
What is the difference between wait in stdlib.h and sys/wait.h o.O ?
In details - I just encountered this problem and I could't compile a simple C program. I isolated the problem and here's what I got:
#include <stdlib.h>
//#include <sys/wait.h>
int main()
{
int status;
wait( &status );
return 0;
}
If stdlib.h is included, I got:
$ gcc asd.cpp
asd.cpp: In function ‘int main()’:
asd.cpp:9:16: error: conflicting declaration ‘wait& status’
asd.cpp:8:6: error: ‘status’ has a previous declaration as ‘int status’
What declaration ? O.o What is wait here, that conflicts with int status?
I found a thread in the net, where replacing stdlib.h with sys/wait.h solves the problem, but why is that and what is the difference?
EDIT: Thanks to sidyll's comment, I changed the file extention - from .cpp to .c and it worked! I'm shocked :) How is this so different? And still the same question - what is the different between those two wait-s ?
The difference is that the wait() in <sys/wait.h> is the one you should use.
From the wait(3) man page:
SYNOPSIS
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
The wait function isn't defined by the ISO C standard, so a conforming C implementation isn't allowed to declare it in <stdlib.h> (because it's legal for a program to use the name wait for its own purposes). gcc with glibc apparently does so in its default non-conforming mode, but if you invoke it with gcc -ansi -pedantic or gcc -std=c99 -pedantic, it doesn't recognize the function name wait or the type pid_t.
I did gcc -E wait.cpp to dump the actual preprocessor expansions that take place. What I found was that on linux, the header /usr/include/bits/waitstatus.h is included which pulls in a union wait { ... } but the function wait() from sys/wait.h is never pulled in. The same thing happens with the c compilation, but the for whatever reason the compiler does not complain in that case.
To prove this to yourself, you can change your main to declare the wait as a variable rather than a function call, and the compiler will not complain:
int main() {
int status;
wait w;
return 0;
}
Note that GCC stands for GNU Compiler Collection, not GNU C Compiler (as many
other tools which were prefixed with a g). It's not a C-only compiler. And
many languages are detected by file extensions. Adam Rosenfield is partialy
correct in his comment. Yes, g++ will add the C++ library in the linker phase,
but that's not the unique difference (more on this later).
To explain how changing the extension solved it, please take a look in this text
straight from GCC's manual:
Compiling C++ Programs
C++ source files conventionally use one of the suffixes.C, .cc, .cpp,
.CPP, .c++, .cp,or.cxx;C++ header files often use.hhor.H;and
preprocessed C++ files use the suffix .ii. GCC recognizes files with
these names and compiles them as C++ programs even if you call the
compiler the same way as for compiling C programs (usually with the
namegcc).
So, "GCC regocnizes files with these names" and your program was being compiled
as C++ source. I guess that C++ has some special use of &, which I can't tell
exactly (I don't know C++). Hence the error.
Now, regarding the difference between g++ and gcc, continue with the next
paragraph:
However, the use ofgccdoes not add the C++ library.g++is a program
that calls GCC and treats.c, .hand.ifiles as C++ source files
instead of C source files unless-xis used, and automatically
specifies linking against the C++ library. This program is also useful
when precompiling a C header file with a.hextension for use in C++
compilations. On many systems,g++is also installed with the name
c++.
On the real question: there aren't two waits here in my system (Darwin 11), only
the standard syscall. Check if what Kevin said isn't happening. It's the same,
stdlib.h includes sys/wait.h:
#include <_types.h>
#if !defined(_ANSI_SOURCE)
#include <sys/wait.h>
#if (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
#include <alloca.h>
#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
#endif /* !_ANSI_SOURCE */
Check your header.

Resources