What Is the Purpose of Features.H Header

Why not should you not include features.h?

glibc guarantees that #defines of the documented feature selection macros (_POSIX_C_SOURCE, _XOPEN_SOURCE, _GNU_SOURCE, etc) will be honored as long as they take effect before the first inclusion of any public C library header. For instance

/* file header comment */
#define _XOPEN_SOURCE 700 // first non-comment line of the file
#include <unistd.h> // first #include in the file
// ... more code here ...

is guaranteed to make unistd.h declare things that are part of POSIX.1-2008 including XSI extensions.

The implementation of this guarantee involves features.h, but features.h is not a public C library header. Direct inclusion of features.h is not something you should ever need to do, and we (glibc devs) do not promise that this header will even continue to exist in the future. (For instance, a future release might merge it into bits/libc-header-start.h.)

*.h or *.hpp for your class definitions

Here are a couple of reasons for having different naming of C vs C++ headers:

  • Automatic code formatting, you might have different guidelines for formatting C and C++ code. If the headers are separated by extension you can set your editor to apply the appropriate formatting automatically
  • Naming, I've been on projects where there were libraries written in C and then wrappers had been implemented in C++. Since the headers usually had similar names, i.e. Feature.h vs Feature.hpp, they were easy to tell apart.
  • Inclusion, maybe your project has more appropriate versions available written in C++ but you are using the C version (see above point). If headers are named after the language they are implemented in you can easily spot all the C-headers and check for C++ versions.

Remember, C is not C++ and it can be very dangerous to mix and match unless you know what you are doing. Naming your sources appropriately helps you tell the languages apart.

`gcc -E -P -C` adds extra comments

The comments seem to contain the explanation of what's going on, particularly the parts that say compiler can include it implicitly at the start of every compilation and GCC knows the name of this header in order to preinclude it.

There's a gcc bug report that looks very similar to your question that was resolved by the use of -nostdinc.

features.h not found solus linux, what is it and how do I get it?

Please install the system.devel component. Installing a compiler alone is not sufficient, you need headers and libraries too.

sudo eopkg it -c system.devel

Think of it as our equivalent to build-essential

Include of stdint.h in a header file breaks compiling with clock_gettime()

As rici pointed out, POSIX requires that (re)definitions of any of the feature test macros it specifies precede inclusion of any of the headers it specifies, including by other header files, else behavior is undefined. The _POSIX_C_SOURCE macro is such a feature-test macro, and stdint.h and time.h are both such headers.

In your particular case, the GNU C library's stdint.h header and many others rely on a common internal header (features.h) that checks which features are explicitly enabled and sets all the feature macros to consistent values (inasmuch as that is possible). It may both check the value of the _POSIX_C_SOURCE macro and set it if it was not already set. It uses a standard guard macro to avoid being processed multiple times. Therefore, if a feature macro is redefined later then you risk inconsistent feature definitions.

I have not traced down the exact chain of definitions and redefinitions that causes clock_gettime() to fail to be declared in your particular case (and indeed, you have not presented enough information for me to do so), but if you are going to define feature macros then you should ensure that all headers see those definitions. They should appear in your source file before any #include directives, and you should avoid otherwise causing any system headers to be preprocessed before those definitions (e.g. via a directive in the file named in your -include option).

Note, too, that although we're discussing implementation details, there is no reason to suppose that GNU's implementation is unusual in this respect. Others will be implemented somewhat differently, but it is always wise to ensure that all headers see a consistent set of definitions for any macros that affect them. Even for macros that are not specified by POSIX.



Related Topics



Leave a reply



Submit