Можно ли получить макрос, передаваемый в качестве необязательного аргумента в функцию variadi c, используя va_arg? - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть программа ниже. Он передает макрос в качестве необязательного аргумента функции variadi c. В пределах этого определения функции мы сможем получить этот макрос без расширения. Я использовал тип как 'char *' и показывает расширенную строку макроса. Любые способы получить макрос как есть.

#include <stdio.h>
#include <stdarg.h>

#define CONN_DISALLOW 3201008
#define SYSLOG_CONN_DISALLOW  \
    "%d: Disallowing new connections. Reason: %s.\n", CONN_DISALLOW

void cp_syslog(int syslogid, ...);

void cp_syslog(int syslogid, ...)
{
        char *syslog_disallow;
        va_list ap;
        va_start(ap, syslogid);

        syslog_disallow = va_arg(ap, char *);

        printf("String is %s", syslog_disallow);
        printf("Macro is %s", SYSLOG_CONN_DISALLOW);

        va_end(ap);
}

int main()
{
        int id = 2;
        cp_syslog(id, SYSLOG_CONN_DISALLOW);
        return 0;
}

Теперь получил вывод в виде:

String is %d: Disallowing new connections. Reason: %s.
Macro is %d: Disallowing new connections. Reason: %s.

Ожидается как:

String is SYSLOG_CONN_DISALLOW

Здесь я ожидаю, как обработать определенный макрос, если разные макросы передается в качестве необязательного аргумента той же переменной c fun c.

, как показано ниже:

cp_syslog(id, SYSLOG_CONN_DISALLOW);
cp_syslog(id, SYSLOG_CONN_ALLOW);
cp_syslog(id, SYSLOG_ICMP_DISALLOW);

1 Ответ

1 голос
/ 22 апреля 2020

Первая возможность состоит в том, чтобы просто сделать

cp_syslog(id, "SYSLOG_CONN_DISALLOW");

Выполнение:

pi@raspberrypi:/tmp $ ./a.out
String is SYSLOG_CONN_DISALLOWMacro is %d: Disallowing new connections. Reason: %s.
pi@raspberrypi:/tmp $ 

(новая строка пропущена в первом printf или сделать cp_syslog(id, "SYSLOG_CONN_DISALLOW\n"))

Но это искусственно, и даже определение cp_syslog искусственно, потому что известно, что макрос SYSLOG_CONN_DISALLOW находится в его определении.


Если вы хотите дать «что-то еще» 'и имя макроса, и его' значение 'просто используют промежуточный макрос, например:

#define NAME_VALUE(x) #x, x

Расширение NAME_VALUE(SYSLOG_CONN_DISALLOW) равно "SYSLOG_CONN_DISALLOW", "%d: Disallowing new connections. Reason: %s.\n", 3201008

В это время cp_syslog делает не нужно знать, что это относится к SYSLOG_CONN_DISALLOW:

#include <stdio.h>
#include <stdarg.h>

#define CONN_DISALLOW 3201008
#define SYSLOG_CONN_DISALLOW  \
    "%d: Disallowing new connections. Reason: %s.\n", CONN_DISALLOW

#define NAME_VALUE(x) #x, x /* ADDED */

void cp_syslog(int syslogid, ...);

void cp_syslog(int syslogid, ...)
{
  char *syslog_disallow;
  va_list ap;
  va_start(ap, syslogid);

  syslog_disallow = va_arg(ap, char *);

  printf("String is %s\n", syslog_disallow); /* \n ADDED */
  printf("Macro is %s", va_arg(ap, char *)); /* MODIFIED */

  va_end(ap);
}

int main()
{
        int id = 2;
        cp_syslog(id, NAME_VALUE(SYSLOG_CONN_DISALLOW)); /* MODIFIED */
        return 0;
}

Компиляция и исполнение:

pi@raspberrypi:/tmp $ gcc pp.c
pi@raspberrypi:/tmp $ ./a.out
String is SYSLOG_CONN_DISALLOW
Macro is %d: Disallowing new connections. Reason: %s.
pi@raspberrypi:/tmp $ 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...