Одним из решений может быть наличие нескольких файлов .c для каждого модуля, одного производственного кода и одного тестового кода, а также компиляция и связь с одним из двух. Глобальные и функциональные сигнатуры в обоих файлах .c должны быть как минимум одинаковыми (как минимум: символов может быть больше, но не меньше).
Другое решение, основанное на предыдущем, состоит в том, чтобы иметь две библиотекиодин с рабочим кодом, другой с тестовым кодом, и связь с одним из обоих. Вы можете даже связать обе библиотеки с первой тестовой версией, поскольку компоновщики часто разрешают символы в том порядке, в котором они встречаются.
И, как вы сказали, вы можете работать с кучей #ifdef
с,что имело бы преимущество иметь только один файл .c, но делая код менее читабельным.
Я бы не стал использовать #ifdef
s на уровне функций, то есть определяя только одну функцию файла .cдля проверки и сохранения других как есть;однако, если необходимо, это может быть далеко. И если необходимо, вы можете иметь один файл .c (два) для каждой функции, но это отрицает концепцию модуля.
Я думаю, что первый подход будет самым чистым.