Constants

The identifiers of constants can be reused but the values of old constant can never be reused.

Reusing identifiers should likely be avoided outside of a soft-break. You could end up with confusion as new compiles ask for new behaviors they are not aware of or can handle.

Deprecation

Mark the identifier as deprecated in documentation. If plausible also emit warnings in runtime or compile logs that a symbol is being used that no longer should be.

(Soft Removal) Rename the constant or enum if your language cares about enum holes. Such as putting "_DEPRECATED" on the name. Alternatively you can remove the enum but you will need to make sure other elements retain the correct index.

This will hard break new compiles but not affect software in the wild.

/* soft deletion */
typedef enum _kind {
    ctMD5_Broken = 1, /* _Broken discourages use */
    ctGoodHash = 2,
    ctPostQuantumHasb = 3
} kind_e;

/* hard deletion */
typedef enum _kind {
    /* there is a hole here; but some languages hate that */
    ctGoodHash = 2,
    ctPostQuantumHash = 3
} kind_e;

Rationale

Constants are baked in at compile-time. So old software will always give the old values. New software can use the new values at the same identifiers.