HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

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

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
generatedheaderinitializingcompiletimeusingspecificmachinedatastatic

Problem

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 wri

Solution

-
You don't want to define objects in the .h file. Two .c files independently including constants.h would result in multiple definition error at link time. So, a constants.h should declare the variables as extern, and another autogenerated constants.c file shall define them.

-
The approach makes portability at the binary level questionable. The generated constants are only valid for a machine the code was compiled at.

-
You may be interested in how initialization problem is addressed in gcc.

Context

StackExchange Code Review Q#114417, answer score: 4

Revisions (0)

No revisions yet.