# Initializing static, machine-specific data in C using a compile-time generated header

I'm using some rather old C code (circa 1996, written in K&R style) to do robust geometric computations, available here, for a library I'm trying to write. In order to work properly, this code has to execute an initializer function before calling any of the included routines:

void exactinit()
{
REAL half;
REAL check, lastcheck;
int every_other;

every_other = 1;
half = 0.5;
epsilon = 1.0;
splitter = 1.0;
check = 1.0;
/* Repeatedly divide `epsilon' by two until it is too small to add to    */
/*   one without causing roundoff.  (Also check if the sum is equal to   */
/*   the previous sum, for machines that round up instead of using exact */
/*   rounding.  Not that this library will work on such machines anyway. */
do {
lastcheck = check;
epsilon *= half;
if (every_other) {
splitter *= 2.0;
}
every_other = !every_other;
check = 1.0 + epsilon;
} while ((check != 1.0) && (check != lastcheck));
splitter += 1.0;

/* Error bounds for orientation and incircle tests. */
resulterrbound = (3.0 + 8.0 * epsilon) * epsilon;
ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon;
// SNIP, compute some more things just like this
isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon;
}

The variables resulterrbound, ccwerrboundA, etc. are global variables that are set in this function and used to determine whether the result of a given geometric predicate can be trusted or not, due to floating point errors.

The problem I'm trying to address is that I don't want the user to have to call exactinit() or any other initialization procedures at the beginning of every program which uses my library just because I use this other guy's code. I've found a workaround which I would like some critique on.

The global data that exactinit computes is just some machine-dependent constants and a few derived quantities, i.e. it does not change from one program invocation to the next. What I've done instead is write a program which computes all of the same constants that exactinit does and writes them to a header file, which the main library sources then include.

/* make_constants_h.c */
error_bounds_t compute_error_bounds()
{
// SNIP, it's more or less the same as exactinit but it packs
// everything into a struct
}

void write_error_bounds(const char * filename, error_bounds_t err_bounds)
{
FILE * fid = fopen(filename, "w");
fprintf(fid, "#ifndef CONSTANTS_H\n");
fprintf(fid, "#define CONSTANTS_H\n");

fprintf(fid, "const double epsilon = %a;\n", err_bounds.epsilon);
fprintf(fid, "const double resulterrbound = %a;\n", err_bounds.resulterrbound);
// SNIP, write the other constants to the header file
}

int main(int argc, char ** argv)
{
write_error_bounds(argv[1], compute_error_bounds());
return 0;
}

In order to generate the header file and include it in the library, I use custom commands and targets in CMake:

add_custom_command (OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/constants.h COMMAND${CMAKE_CURRENT_BINARY_DIR}/make_constants_h ${CMAKE_CURRENT_BINARY_DIR}/constants.h DEPENDS make_constants_h) add_custom_target (constants_h ALL DEPENDS${CMAKE_CURRENT_BINARY_DIR}/constants.h)

include_directories(${CMAKE_CURRENT_BINARY_DIR}) # SRCS is the list of all library sources, set elsewhere add_library (predicates SHARED${SRCS})

I probably could have done this with a simple Makefile, but I used CMake for everything anyway. Point is, I use the build system to invoke the program that generates the header file.

So, what I would like some feedback on is whether generating a header file is or isn't a good idea. Since initializing the program data requires executing a loop, I can't just use preprocessor defines for everything. (Strictly speaking I could just #define epsilon to be 1.0/2^53, but I'd like to preserve as much of the original code as possible.) I can't think of any libraries offhand that do this, but I find the thought of generating a short header file to be much more palatable than forcing the user to invoke some function at the beginning of every program.

All of the code for this is available here.

• you could have the entry points in your library, which depend on those values being set properly, check a 'new' flag the is initialized to 'false' that, if false, calls the (hidden) function and sets the flag to 'true' That way, the user has to do nothing special and the function will always be called when necessary – user3629249 Dec 19 '15 at 0:18
• Have you tried compiling the posted code? It does not compile. It does cause the compiler to output several warnings and errors. when compiling, always enable all the warnings, then fix them. (for gcc, at a minimum use: -Wall -Wextra -pedantic ) You could start fixing them by replacing the main() signature statement with: int main( void ) – user3629249 Dec 19 '15 at 0:23
• Using the %a format conversion specifier results in a hex output of a double argument in this format: [-]0xh.hhhhp±; Probably not what you want to do. – user3629249 Dec 19 '15 at 0:42
• I actually do want the output in hex in order to avoid any potential rounding in converting to/from decimal. The code compiles for me under clang but throws a bunch of warnings relating to standard usage in gcc, let me see if I can fix that -- thanks for the heads up! – korrok Dec 19 '15 at 1:19