> Furthermore, that does not stop an enthusiastic programmer from > feeding the interface functions with the wrong values
If you seed the first enum from DATESTAMP, and properly range check, you can find these cases pretty quickly and abort. TVQ_SEED = (DATESTAMP%10) * 1000, TVQ_FOO1, ... > if he is supposed to convert between integers and enums. I can't imagine any situation where the programmer is *supposed* to feed integers where enums are expected, in the cases where we're trying to hide the names (like machine_mode). I think the problem you're trying to solve is enumerations that, for example, define an ABI to hardware or something, where they *must* have specific values. Still, you can use the DATESTAMP trick, and offset it in the authoritative functions to get the needed integer values. enum { TVQ_SEED = (DATESTAMP%10) * 1000, TVQ_NOP, TVQ_READ, TVQ_WRITE } tvq_dma_command; int tvq_dma (tvq_dma_command cmd) { *port = (int)cmd - ((int)TVQ_SEED+1); } If you really must stop people from using integers found in ABI manuals, list the enums in reverse order. You can still use math to find the right integers, but you can't use TVQ_NOP+2 to mean "the chip expects a 2". Worse, use a random order and a private lookup table ;-)