2015-07-02 3 views
0

Можно ли отключить куски кода с препроцессором c/C++ в зависимости от определенного определения, без кода с кодом #ifdef #endif?Отключить многострочные операторы с макросом c/C++

// if ENABLE_TEST_SONAR is not defined, test code will be eliminated by preprocessor 
TEST_BEGIN(SONAR) 
    uint8_t sonar_range = get_sonar_measurement(i); 
    TEST_ASSERT(sonar_range < 300) 
    TEST_ASSERT(sonar_range > 100) 
TEST_END 

Аналогична что-то выглядит следующим образом:

#ifdef TEST_SONAR 
    serial_print("test_case sonar:\r\n"); 
    uint8_t sonar_range = get_sonar_measurement(i); 
    serial_print(" test sonar_range < 300:%d\r\n", sonar_range < 300); 
    serial_print(" test sonar_range > 100:%d\r\n", sonar_range > 100); 
#endif TEST_SONAR 
+6

Почему? Это буквально то, что '# ifdef' за ......... говорит о повторной разработке колеса .... –

+0

Мне также нужно добавить дополнительную функциональность для TEST_BEGIN, так что просто хотел сделать это в одном линия. – DikobrAz

+0

Вы можете быть немного более лаконичными с «отключить»? Вы имеете в виду генерировать код, связывать его, но не выполнять его? – Dinesh

ответ

2

Несколько строк можно отключить только с помощью #ifdef или #if, но отдельные строки можно отключить с помощью макроса. Обратите внимание, что несколько строк могут быть объединены с \

#ifdef DOIT 
#define MYMACRO(x) \ 
some code \ 
more code \ 
even more \ 
#else 
#define MYMACRO(x) 
#endif 

Тогда при вызове MYMACRO anplace этого кода будет либо включены или не основано на ли DOIT определяется

Это ближайшее вы можете прийти и часто используются для отладки кода

EDIT: на прихоти я попытался следующие, и это похоже на работу (в MSVC++ и г ++):

#define DOIT 
#ifdef DOIT 
#define MYMACRO(x) x 
#else 
#define MYMACRO(x) 
#endif 

void foo(int, int, int) 
{ 
} 

int main(int, char **) 
{ 
    int x = 7; 
MYMACRO(
if (x) 
return 27; 
for (int i = 0; i < 10; ++i) 
    foo(1, 2, 3); 
) 

} 
+0

Да, если бы у меня был только один макрос для управления всеми тестами, я бы пошел с этим подходом, но я, вероятно, хочу выборочно включать и отключать тесты. – DikobrAz

+0

@ DikobrAz последнее редактирование может помочь –

+0

Спасибо, я думаю, что решение в редактировании - это то, за что я должен идти. – DikobrAz

1

Нет, единственный способ отключить разделы кодов эффективно с использованием предварительной обработки является #ifdef #endif. Теоретически, вы можете использовать #if identifier, но лучше придерживаться проверки того, определена ли переменная.

Другой вариант (возможно) является использование предварительной обработки макроса:

Edit:

Возможно, используя простые функции и #ifdef могли бы работать лучше?

function test_function() { 
    /* Do whatever test */ 
} 
#define TESTING_IDENTIFIER 
#define TEST(i, f) if ((i)) do { f } while (0) 

Тогда для каждого теста можно определить уникальный идентификатор и назвать его, предоставляя идентификатор первого и функции (с скобка) секунды.

TEST(TESTING_IDENTIFIER, test_function()); 

Наконец, f может быть все, что синтаксически правильно - Вы не должны создать функцию для каждого теста, вы можете поместить встроенный код.

+0

Я не думаю, что вы можете поставить/*, */in macro – DikobrAz

+0

Не скопированы макросы verbatim – Isaiah

+0

Я думаю, что удаление комментариев просто до макрорасширения https://ideone.com/mVgzaU – DikobrAz

0

я все равно уже очевидное решение

#define DO_TEST_SONAR 
#ifdef DO_TEST_SONAR 
#define TEST_SONAR if(true) { 
#else 
#define TEST_SONAR if(false) { 
#endif 
#define TEST_SONAR_END } 

... 
TEST_SONAR 
code 
TEST_SONAR_END 

код будет еще компилируются, не полностью удалены, но некоторые умные компиляторы могли бы оптимизировать его.

UPD: только протестировано и

#include <iostream> 
using namespace std; 

//#define DO_TEST_SONAR 
#ifdef DO_TEST_SONAR 
#define TEST_SONAR if(true) { 
#else 
#define TEST_SONAR if(false) { 
#endif 
#define TEST_SONAR_END } 

int main() { 
TEST_SONAR 
cout << "abc" << endl; 
TEST_SONAR_END 
} 

производит абсолютно одинаковые двоичные файлы с cout линии закомментирована и не заметил, так что на самом деле код удаляется. Используя g ++ 4.9.2 с -O2.

Смежные вопросы