I am porting a windows library to linux. I need to use timed join to wait for the thread to join in a specific timeout.
When I compile the library on Linux I am getting the warning
Implicit declaration of the function - pthread_timedjoin_np
I have included pthread.h and have compiled with -lpthread link. I know that pthread_timedjoin_np is a non-standard GNU function. The function first appeared in glibc in version 2.3.3. and somewhere in BCD v6.
I even checked the Man Page for Linux but got no help. How do I avoid this warning? Any help?
Edit-1:
My system is RedHat 5.
Make sure the #define _GNU_SOURCE is before any of the your headers are included. Macros are set up by <features.h>, which include various parts of the GNU C library. If you've included other headers before you define _GNU_SOURCE, <features.h> will have already been included and will have not seen _GNU_SOURCE.
Even easier, just define it with the compiler adding -D_GNU_SOURCE as a compiler flag.
Related
I am doing an assignment which states: "The skeleton code given uses getopt. If you compile the code with -std=c99, there will be compilation
error. To fix the error, include -D_POSIX_C_SOURCE=200809 when you compile the code."
I am very new to this. Ordinarily I compile a C program with GCC (program name) and then I type ./a.out.
What am I required to do here?
The sentence “To fix the error, include -D_POSIX_C_SOURCE=200809 when you compile the code” means to include the characters -D_POSIX_C_SOURCE=200809 in the command you use to compile the program.
For example, if you normally use gcc -o foo foo.c, change it to gcc -o foo -D_POSIX_C_SOURCE=200809 foo.c.
This is a command line argument that tells the compiler to define a preprocessor macro named _POSIX_C_SOURCE to be replaced by 200809. This preprocessor macro is used by various header files to adapt to different versions of POSIX (by using #if statements to test the macro). For example, if you specify _POSIX_C_SOURCE to be 200809 or leave it undefined, the headers will not declare routines that were only added to POSIX after the 2008-09 version of POSIX. Among other things, this avoids causing conflicts with programs written before then that might have happened to use names of those routines for other purposes (since they would have had no way of knowing what names POSIX header would define in the future).
You can also define the macro in your source code, before any headers that use it are included, with:
#define _POSIX_C_SOURCE 200809
The getopt function is a relatively recent addition to the Single UNIX Specification/POSIX Standard. While Linux doesn't comply with POSIX, it does roughly use this standard as a reference point. However, it's mostly implementing XSH (System Headers) of POSIX '03 or earlier by default for compatibility. If you want more recent additions exposed (Note: #JonathanLeffler mentions that getopt is there for quite some time already, but Linux doesn't expose it by default anyway), you can tell the GNU libc (the C Library commonly used on GNU/Linux systems) to also provide some of that functionality which are hidden behind Feature Test Macros. Lookup the man-page man -s 7 feature_test_macros 2 in combination with man -s 3 getopt 1 for more. Basically, in the respective headers there's some code similar to the following:
#if _POSIX_C_SOURCE >= 200809L
/* declaration of getopt() and other newer functions */
#endif
If you then include that file and do not define the feature test macro to have a value greater than (newer/more recent than) the date of that POSIX standard you need (2008-09), the C Preprocessor will throw away all those forward declarations, making your code error out.
Using -DFOO=bar you #define FOO bar on the command line for the standard C Compiler. By the way, the GNU C Compiler also sets some of such flags when you use -std=c99.
In the end, your command line should look more or less like this:
$ c99 -D_POSIX_C_SOURCE=200809L -o foo foo.c
This will compile and link foo.c to the output file foo adhering to the C99 standard and using features from POSIX '08 3.
I recently took a class where we used pthreads and when compiling we were told to add -lpthread. But how come when using other #include <> statements for system header files, it seems that the linking of the object implementation code happens automatically? For example, if I just want to get the header file #include <stdio.h>, I don't need a -l option in compilation, the linking of that .o implementation file file just happens.
For this file
#include <stdio.h>
int main() {
return 0;
}
run
gcc -v -o simple simple.c
and you will see what, actually, gcc does. You will see that it links with libraries behind your back. This is why you don't specify system libraries explicitly.
Basic Answer: -lpthreads tells the compiler/linker to link to the pthreads library.
Longer answer
Headers tell the compiler that a certain function is going to be available (sometimes that function is defined in the header, perhaps inline) when the code is later linked. So the compiler marks the function essentially available but later during the linking phase the linker has to connect the function call to an actual function. A lot of function in the system headers are part of the "C Runtime Library" your linker automatically uses but others are provided by external libraries (such as pthreads). In the case where it is provided by an external library you have to use the '-lxxx' so the compiler/linker knows which external library to include in the process so it gets the address of the functions correctly.
Hope that helps
A C header file does not contain the implementations of the functions. It only contains function prototypes, so that the compiler could generate proper function calls.
The actual implementation is stored in a library. The most commonly used functions (such as printf and malloc) are implemented in the Standard C Library (LibC), which is implicitly linked to any executable file unless you request not to link it. The threads support is implemented in a separate library that has to be linked explicitly by passing the -pthread option to the linker.
NB: You can pass the option -pthread to the compiler that will also link the appropriate library.
The compiler links the standard C library libc.a implicitly so a -lc argument is not necessary. Pthreads is a system library but not a part of the C standard library, so must be explicitly linked.
If you were to specify -nolibc you would then need to explicitly link libc (or some alternative C library).
If all system libraries were linked implicitly, gcc would have to be have a different implementation for each system (for example pthreads is not a system library on Windows), and if a system introduced a new library, gcc would have to change in lock step. Moreover the link time would increase as each library were searched in some unknown sequence to resolve symbols. The C standard library is the one library the compiler can rely on to be provided in any particular implementation, so implicit linking is generally safe and a simple convenience.
Some library files are are searched by default, simply for convenience, basically the C standard library. Linkers have options to disable this convenience and have no default libraries (for if you are doing something unusual and don't want them). Non-default libraries, you have to tell linker to use them.
There could be a mechanism to tell what libraries are needed in the source code (include files are plain text which is just "copy-pasted" at #include line), there's no technical difficulty. But there just isn't (as far as I know, not even as non-standard compiler extension).
There are some solutions to the problem though, such as pkg-config for unixy platforms, which tackle the problem of include and library files by providing the compiler and linker options for a library easily.
the -l option is for linking against an external library in this case libpthread, against system libraries is linked by default
http://www.network-theory.co.uk/docs/gccintro/gccintro_17.html
C++: How to add external libraries
I am currently writing a C program with threads and I make use of pthread_cleanup_push_defer_np() and pthread_cleanup_pop_restore_np(). Provided that:
I have included pthread.h;
I am compiling with -pthread option;
I am on Ubuntu 14.04 and using gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1);
when compiling I get back a nasty undefined reference error to the above mentioned functions and I can't figure out why. I have tried to take a look into pthread.h and it seems those two functions are commented out, so I am wondering whether I need to enable them in some way or use some other kind of options. I've read the manual pages and google it up but I can't find a solution, so I would appreciate a little help. Here it is a snippet:
void *start_up(void *arg)
{
char *timestamp;
// ... code ...
timestamp = get_current_timestamp("humread");
pthread_cleanup_push_defer_np(free, timestamp);
// ... some other code
pthread_cleanup_pop_restore_np(1);
// ... more code ...
}
I compile with
gcc -pthread -o server *.c
The manual of pthread_cleanup_push_defer_np and pthread_cleanup_pop_restore_np say these two (non portable) functions are GNU extensions and are enabled
by defining _GNU_SOURCE:
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
pthread_cleanup_push_defer_np(), pthread_cleanup_pop_defer_np():
_GNU_SOURCE
This results in linker error (as opposed to compile time error) because your compiler is pre-C99 (or you are compiling in pre-C99 mode) and assumes these functions return int by default.
The rule functions-return-int if no prototype is present has been removed since C99. Enabling more compiler switches can help you with better diagnostics.
#include <sys/syscall.h>
#define BUFSIZE 1024
main()
{
char buf[BUFSIZE];
int n;
while((n=read(0,buf,BUFSIZE))>0)
write(1,buf,n);
return 0;
}
When I compile this by using gcc, it is fine.
But use g++ I got :
inandout.c:7:32: error: ‘read’ was not declared in this scope
while((n=read(0,buf,BUFSIZE))>0)
^
inandout.c:8:22: error: ‘write’ was not declared in this scope
write(1,buf,n);
^
Why is that?
This is because gcc is a C compiler, g++ is a C++ compiler, and C and C++ are different languages.
If you want to compiler that source code as C++ program, you must change it to become C++. For example, there are no implicit function declarations in C++, so you must include unistd.h for read() and write() declarations. You also don't need syscall.h header.
Also, it is only that simple because you have a simple code snippet. Porting C code to C++ could be a nightmare as there are ~ 50 differences and in some cases code compiles well in both cases, but behaves differently.
P.S.: And instead of defining weird BUFSIZE yourself, consider using standard BUFSIZ :)
You Just need to add include <unistd.h>
C defaults functions that do not have a prototype to a function that returns an int - but you should have got warnings for that (did you use -Wall?).
C++ doesn't allow that, you need to include the correct header file, unistd.h, which you should also do in C.
I upgraded to gcc 4.8.5. In version 4.7 the compiler stopped including unistd.h in a number of include files. This is why older gcc compiler versions worked without including unistd.h.
https://gcc.gnu.org/gcc-4.7/porting_to.html
"C++ language issues
Header dependency changes
Many of the standard C++ library include files have been edited to no longer include unistd.h to remove namespace pollution. "
In my case I got ::write has not been declared when I included stdio.h, but my previous gcc version 4.4 compiled fine. This is a useful command to see what paths are being searched by the preprocessor: g++ -H test.cpp
I use dev c++ for my c projects,because it's simple for me.I installed it with the mingw extension.Well,I included stdlib.h and made a call to mrand which according to manpages belongs to that header but I got a linker error.I looked in mingw's headers and found no declaration for mrand although the glibc has one in stdlib.Am I missing something?I thought mingw and gcc were the same.If they are different I suppose that there isn't a way to get gcc's full power.Right?Thank you.
mrand is not part of the standard C library, nor is it present in standard Linux manpages. Whatever compiler you previously used may have had it as a proprietary extension, but since you haven't mentioned which (it's not GCC or MSVC, at least), I can't tell what mrand is supposed to do, and so it's hard to suggest an alternative function to use.
Note that glibc does offer a mrand48(). Since this is a POSIX function, not a standard C function, it may or may not be present in other C libraries - but note that this is a function of the C library (glibc), not the compiler (gcc/mingw).