Can we use POSIX C libraries in C ++?
I am new to Linux systems programming. I am currently programming in C and want to switch to C ++.
Can we use all the functions defined in the POSIX C C ++ libraries without any modification?
Basically, you should be able to use any C API from C ++; the language includes functions to facilitate it, and most C library authors know that people want to do this and will take the appropriate steps. For system programming interfaces specified in POSIX, C ++ compatibility is an explicit design goal.
However, you may still run into problems. In my experience, the most common problems are:
- API headers The API often dumps hundreds of characters into the global namespace. Some of these symbols can conflict with symbols in the C ++ library, which can get you in trouble if you
using namespace std
(but you didn't, did you?) - Macros are often used in API headers, including macro names that may conflict with symbols in the C ++ library;
std::
will not keep you there. - Compiling your program in strict match mode (for example
-std=c++11 -D_XOPEN_SOURCE=700
) can reveal errors in system headers. This is more likely to happen with C ++ than C. - A small subset of POSIX APIs have abnormal control flow behavior that can interact poorly with C ++ exceptions and destructors, depending on how careful your C library developer has been to avoid the problem.
setjmp
andlongjmp
obviously concern here (someone made the C library implementing the tops of exception handling DWARF style?) but alsofork
,setcontext
and friendspthread_cancel
,pthread_cleanup_push
and perhaps a few others I can not remember from the head. (I remember a giant, ultimately flimsy argument between Ulrich Drepper and the CCC C ++ guys back in 2004 or so of exactly how onepthread_cancel
should behave in the presence of destructors.)
If you go outside of POSIX you may also have problems with:
- Headers that didn't bother to wrap all the declarations in a
extern "C"
block when compiled in C ++, which means all function names get malformed when they shouldn't, and the linking fails. - Headers that didn't even bother sticking to the intersection of C and C ++. In the worst case, this can lead to crashes that do not appear until the program is started. The most common examples of this are:
- Blithely using some C ++ keyword as the declared name (for example
int template;
) - Assuming that
void *
is an assignment that is compatible with other types of pointers (e.g. no need to emit a resultmalloc
) - Assuming it
struct foo;
doesn't define a typedef-namefoo
- Blithely using some C ++ keyword as the declared name (for example
Note that headers referenced by POSIX often contain system extensions that have not been as carefully thought out as the POSIX interfaces themselves.
"Can we use all the functions defined in the POSIX C C ++ libraries without any changes?"
Of course you can. Any c-style API can be easily used in C ++.