Can the C Preprocessor Be Used to Tell If a File Exists

Can the C preprocessor be used to tell if a file exists?

Generally this is done by using a script that tries running the preprocessor on an attempt at including the file. Depending on if the preprocessor returns an error, the script updates a generated .h file with an appropriate #define (or #undef). In bash, the script might look vaguely like this:

cat > .test.h <<'EOM'
#include <asdf.h>
EOM
if gcc -E .test.h
then
echo '#define HAVE_ASDF_H 1' >> config.h
else
echo '#ifdef HAVE_ASDF_H' >> config.h
echo '# undef HAVE_ASDF_H' >> config.h
echo '#endif' >> config.h
fi

A pretty thorough framework for portably working with portability checks like this (as well as thousands others) is autoconf.

Can the C preprocessor detect if a header file cannot be found and issue a specific warning?

You could always check if the #define X macro, from the included file, is ... defined :)

Is it posible to check if a struct was defined before (in a header file) during preprocessor?

I have checked in ANSI C spec

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

here
Preprocessing directives only talk about identifier.

so it is NOT possible to check that this structure is defined or not.

Determine compile-time existence of include files in C++

You can't do it without relying on a third party thing before preprocessing. Generally, things like autoconf can be used to accomplish this.

They work by generating another header file with #define directives that indicate existence of headers/libraries you want to use.

How do you include a header file that may or may not exist?

In general, you'll need to do something external to do this - e.g. by doing something like playing around with the search path (as suggested in the comments) and providing an empty foo.h as a fallback, or wrapping the #include inside a #ifdef HAS_FOO_H...#endif and setting HAS_FOO_H by a compiler switch (-DHAS_FOO_H for gcc/clang etc.).

If you know that you are using a particular compiler, and portability is not an issue, note that some compilers do support including a file which may or may not exist, as an extension. For example, see clang's __has_include feature.

How to check (via the preprocessor) if a C source file is being compiled as C++ code

#ifndef __cplusplus

If I remember correctly.

C check if file exists

If you can't use stat() in your environment (which is definitely the better approach), just evaluate errno. Don't forget to include errno.h.

FILE *file;
if ((file = fopen(fname, "r")) == NULL) {
if (errno == ENOENT) {
printf("File doesn't exist");
} else {
// Check for other errors too, like EACCES and EISDIR
printf("Some other error occured");
}
} else {
fclose(file);
}
return 0;

Edit: forgot to wrap fclose into a else

C pre-processor or C++ magic to automatically make an object per file?

Cache the result.

// in the header with Function macro
static FunctionHelperObject functionhelper;
static inline void FunctionModifiableInterface(const char *file, int i) {
static initialized = 0;
if (initialized == 0) {
initialized = 1;
functionhelper = FunctionHelperObject(file);
}
FunctionModifiable(&functionhelper, i);
}
#define Function(i) FunctionModifiableInterface(__FILE__, (i))

You can't predict where the user would want to call you Function(i), so you can't predict the value of __FILE__. Just initialize it on the first call, which also is great, because you will not initialize it if Function is not called. You could do the same initialized check inside FunctionHelperObject constructor.

The really cool and hard to do trick is to modify your build system to allow you to pass a macro with the filename of compiled C file. Because build systems compile one C file at a time, it is possible (and it's a shame compilers doesn't do that by themselves). If you are using cmake with make backend (or really just make by itself), you could do something like this:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__MY_FILE__='\"$(notdir $(abspath $<))\"'")

And then use FunctionHelperObject fho(__MY_FILE__) like you wanted to, because __MY_FILE__ depends only on the output filename from make.



Related Topics



Leave a reply



Submit