Использование #ifdefs для выбора кода создает некрасивые конструкции - альтернативы? - PullRequest
0 голосов
/ 22 января 2019

В настоящее время мой код выглядит примерно так:

#ifdef A
#include "include_a.h"
#endif

#ifdef B
#include "include_b.h"
#endif

void func_A()
{
#ifdef A
    do_stuff_a();
#endif
}

void func_B()
{
#ifdef B
    do_stuff_b();
#else
    do_other_stuff();
#endif
}

void func_C()
{
    do_stuff_c();
}
int main(void)
{
#ifdef A
#ifdef B
    do_AB_stuff();
#else
    do_A_stuff();
#endif
func_A();
func_B();
func_C();
return 0;
}

Причина этого: я использую cmake для компоновки дополнительных библиотек / заголовков.Если эти заголовки / библиотеки связаны, имеет смысл вызывать включенные функции, в противном случае компиляция не удастся.Это позволяет мне запускать программу как с дополнительными библиотеками, так и без них (например, если я просто хочу проверить func_C(), не имея вычислительной перегрузки func_B() и func_A(), или если библиотеки A и B недоступныв системе).
Тем не менее, это делает довольно уродливый код с довольно большим количеством #ifdefs.Таким образом, есть ли способ получить ту же функциональность (предпочтительно управляемую cmake-скриптом), но без необходимости использовать все эти #ifdefs?

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Вы можете создать так называемую библиотеку-заглушку или реализацию, а затем решить, следует ли ссылаться на эту библиотеку или на ту, которая имеет реальную реализацию.

Файл a_stub.c:

#include "include_a.h"

void func_A() {} // Does nothing. Returns a placeholder value if necessary.

Файл a_real.c:

#include "include_a.h"

void func_A() { do_stuff_a(); }

То же самое для B и C. Затем вы выбираете *_real.c или *_stub.c в зависимости от ваших интересов (а именно, в случаях, когда вы определяете A,B и C макросы).

Редактировать: Вероятно, это то, что @Baruch прокомментировал в другом ответе.Я увидел его комментарий после публикации ответа.

0 голосов
/ 22 января 2019

В зависимости от того, насколько большие библиотеки A и B, вы можете писать библиотеки-заглушки с функциями, которые ничего не делают или возвращают жестко запрограммированные значения или что-либо еще, что имеет смысл.Затем вы можете связаться с реальной библиотекой или библиотекой-заглушкой для тестирования func_C()

Например, если API реальной библиотеки просто

include_a.h:

void do_stuff_a();
void do_A_stuff();

Ваши заглушки могут быть:

stub_a.cpp:

void do_stuff_a() {}
void do_A_stuff() {}

Тогда вы можете избавиться от всех #ifdef A и просто связать их с заглушкой, если не используете библиотеку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...