Как проверить, определен ли CLI MACRO (-DMACRO =) или нет - PullRequest
2 голосов
/ 10 июля 2019

Как проверить, определен макрос или нет, когда определение предоставляется во время компиляции.

У меня есть Makefile, который разрешает и передает эту строку ("-DMACRO_TEST=${DEFINED}") при компиляции образца файла C. Переменная DEFINED может иметь или не иметь значение (0 или не ноль). Я хотел знать, как проверить, определен MACRO_TEST или нет, когда сама переменная DEFINED не имеет никакого значения. Это похоже на передачу "-DMACRO_TEST =" при компиляции файла C.

#include <stdio.h>

#ifdef MACRO_TEST
char msg[] = "MACRO_TEST is defined";
#else
char msg[] = "MACRO_TEST is NOT-defined";
#endif

int main ()
{
    printf("msg = %s\n", msg);
    return 0;
}

Вывод командной строки

$ gcc tmp.c -DMACRO_TEST=0
$ ./a.out
msg = MACRO_TEST is defined
$ gcc tmp.c -DMACRO_TEST=
$ ./a.out
msg = MACRO_TEST is defined

при компиляции во втором случае я ожидал, что он вернет

msg = MACRO_TEST is NOT-defined

Ответы [ 3 ]

2 голосов
/ 10 июля 2019

Если вы опустите любой параметр -DMACRO_TEST или явно добавите -UMACRO_TEST (= неопределенный макрос) в командной строке gcc, макрос не будет определен.В этом случае директива препроцессора #ifdef MACRO_TEST будет иметь значение FALSE, и вы получите

char msg[] = "MACRO_TEST is NOT-defined";

в ветви #else.

(при условии, что вы не определили этот макрос вкод.)

1 голос
/ 10 июля 2019

Некоторые распространенные случаи тестирования макросов:

#ifdef MACRO_TEST
  // MACRO_TEST is defined, whatever its content, even empty
  // for example:
  //   -DMACRO_TEST
  //   -DMACRO_TEST=
  //   -DMACRO_TEST=0
  //   -DMACRO_TEST=1
  //   -DMACRO_TEST=abcd
#else
  // MACRO_TEST is not defined, not even with an empty content
#endif

#if MACRO_TEST // it must not be defined as empty (-DMACRO_TEST= --> error)
  // MACRO_TEST has a non-zero integer value
  // for example:
  //   -DMACRO_TEST
  //   -DMACRO_TEST=1    -- equivalent to -DMACRO_TEST
  //   -DMACRO_TEST=23
#else
  // MACRO_TEST has a zero integer value
  // for example:
  //   (not defined at all, then considered as zero)
  //   -DMACRO_TEST=0
  //   -DMACRO_TEST=what
#endif
0 голосов
/ 10 июля 2019

Просто используйте #if xxx. Undefined xxx обрабатывается препроцессором как ноль.


#include <stdio.h>

#if MACRO_TEST
char msg[] = "MACRO_TEST is defined";
#else
char msg[] = "MACRO_TEST is NOT-defined";
#endif

int main ()
{
    printf("msg = %s\n", msg);
    return 0;
}

И вам не нужно указывать значение в командной строке, достаточно просто -Dxxx, и компилятор / препроцессор примет 1:

cc -Wall -DMACRO_TEST defined.c

UPDATE. Все четыре случая:


#include <stdio.h>

#if MACRO_TEST
char msg[] = "MACRO_TEST is defined and non-zero";
#else
char msg[] = "MACRO_TEST is NOT-defined or zero";
#endif

int main (int argc, char**argv)
{
    printf("%s: msg = %s\n", argv[0], msg);
    return 0;
}

#!bin/sh

cc -Wall defined.c -o x
cc -Wall -DMACRO_TEST defined.c -o xd
cc -Wall -DMACRO_TEST=0 defined.c -o xd0
cc -Wall -DMACRO_TEST=1 defined.c -o xd1

./x
./xd
./xd0
./xd1

rm x xd xd0 xd1

результат:


./x: msg = MACRO_TEST is NOT-defined or zero
./xd: msg = MACRO_TEST is defined and non-zero
./xd0: msg = MACRO_TEST is NOT-defined or zero
./xd1: msg = MACRO_TEST is defined and non-zero
...