Можете Вы #define комментарий в C?

Как обычно решается эта проблема?

Использование одиночного писателя - хорошее решение. Таким образом вы гарантируете, что не дублируете работу, и обновляете кластеры с сохранением состояния, используя события в том порядке, в котором они были записаны в хранилище событий.

Я действительно не хочу создавать синглтон-подписчика для каждого кластера, который прослушивает обновления, он делает этот синглтон единственной точкой отказа ...

Это можно легко смягчить, потому что эта одноэлементная служба не имеет состояния, поэтому ее можно легко перезапустить или даже переместить на другой хост в случае сбоя. Если вы используете контейнерный оркестратор (например, Docker Swarm или Kubernetes), это очень просто.

28
задан Mark Amery 27 December 2015 в 11:40
поделиться

10 ответов

Нет, нельзя. Комментарии удаляются из кода перед началом обработки директив предварительной обработки. По этой причине вы не можете включать комментарий в макрос.

Кроме того, не гарантируется, что любые попытки «сформировать» комментарий позже с помощью каких-либо уловок макросов будут работать. От компилятора не требуется распознавать «поздние» комментарии как комментарии.

Лучший способ реализовать то, что вы хотите, - использовать макросы с переменными аргументами в C99 (или, возможно, с помощью расширений компилятора).

29
ответ дан 28 November 2019 в 02:30
поделиться

С99 way:

#ifdef DEBUG
    #define printd(...) printf(__VA_ARGS__)
#else
    #define printd(...)
#endif

Что ж, этот не требует C99, но предполагает, что в версии релиза включена оптимизация компилятора:

#ifdef DEBUG
    #define printd printf
#else
    #define printd if (1) {} else printf
#endif
18
ответ дан Xeor 28 November 2019 в 02:30
поделиться

На некоторых компиляторах (включая MS VS2010) это будет работать,

#define CMT / ## /

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

6
ответ дан Cody 28 November 2019 в 02:30
поделиться

Не проверено: Редактировать: протестировано, используя его сейчас самостоятельно:)

#define DEBUG 1
#define printd(fmt,...) if(DEBUG)printf(fmt, __VA_ARGS__)

требует, чтобы вы не только определили DEBUG, но и дали ему значение, отличное от нуля.

Приложение: также хорошо работает с std::cout

1
ответ дан drahnr 28 November 2019 в 02:30
поделиться

Как отметил Маккей, у вас возникнут проблемы, если вы просто попытаетесь заменить printd на //. Вместо этого вы можете использовать переменные макросы для замены printd функцией, которая ничего не делает, как показано ниже.

#ifndef DEBUG
    #define printd(...) do_nothing()
#else
    #define printd(...) printf(__VA_ARGS__)
#endif

void do_nothing() { ; }

Использование отладчика, такого как GDB, также может помочь, но иногда достаточно быстрого printf.

0
ответ дан Swiss 28 November 2019 в 02:30
поделиться

A common trick is to do this:

#ifdef DEBUG
  #define OUTPUT(x) printf x
#else
  #define OUTPUT(x)
#endif

#include <stdio.h>
int main(void)
{   
  OUTPUT(("%s line %i\n", __FILE__, __LINE__));

  return 0;
}

This way you have the whole power of printf() available to you, but you have to put up with the double brackets to make the macro work.

The point of the double brackets is this: you need one set to indicate that it's a macro call, but you can't have an indeterminate number of arguments in a macro in C89. However, by putting the arguments in their own set of brackets they get interpreted as a single argument. When the macro is expanded when DEBUG is defined, the replacement text is the word printf followed by the singl argument, which is actually several items in brackets. The brackets then get interpreted as the brackets needed in the printf function call, so it all works out.

20
ответ дан 28 November 2019 в 02:30
поделиться

Вы можете поместить весь свой отладочный вызов в функцию, вызвать ее printf_debug и поместить DEBUG внутрь этой функции. Компилятор оптимизирует пустую функцию.

8
ответ дан 28 November 2019 в 02:30
поделиться

The standard way is to use

#ifndef DEBUG
    #define printd(fmt, ...)  do { } while(0)
#else
    #define printd(fmt, ...) printf(fmt, __VA_ARGS__)
#endif

That way, when you add a semi-colon on the end, it does what you want. As there is no operation the compiler will compile out the "do...while"

2
ответ дан 28 November 2019 в 02:30
поделиться

Дело сделано. Не рекомендую. Нет времени проверять, но механизм примерно такой:

 #define printd_CAT(x) x ## x
 #ifndef DEBUG
    #define printd printd_CAT(/)
 #else
    #define printd printf
 #endif

Это работает, если ваш компилятор обрабатывает // комментарии в самом компиляторе (нет такой гарантии, как ANSI, что есть два прохода для комментариев / *).

0
ответ дан 28 November 2019 в 02:30
поделиться

I use this construct a lot:

#define DEBUG 1
#if DEBUG
#if PROG1
#define DEBUGSTR(msg...)        { printf("P1: "); printf( msg); }
#else
#define DEBUGSTR(msg...)        { printf("P2: "); printf( msg); }
#endif
#else
#define DEBUGSTR(msg...)    ((void) 0)
#endif

This way I can tell in my console which program is giving which error message... also, I can search easily for my error messages...

Personally, I don't like #defining just part of an expression...

0
ответ дан 28 November 2019 в 02:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: