Как обычно решается эта проблема?
blockquote>Использование одиночного писателя - хорошее решение. Таким образом вы гарантируете, что не дублируете работу, и обновляете кластеры с сохранением состояния, используя события в том порядке, в котором они были записаны в хранилище событий.
Я действительно не хочу создавать синглтон-подписчика для каждого кластера, который прослушивает обновления, он делает этот синглтон единственной точкой отказа ...
blockquote>Это можно легко смягчить, потому что эта одноэлементная служба не имеет состояния, поэтому ее можно легко перезапустить или даже переместить на другой хост в случае сбоя. Если вы используете контейнерный оркестратор (например, Docker Swarm или Kubernetes), это очень просто.
Нет, нельзя. Комментарии удаляются из кода перед началом обработки директив предварительной обработки. По этой причине вы не можете включать комментарий в макрос.
Кроме того, не гарантируется, что любые попытки «сформировать» комментарий позже с помощью каких-либо уловок макросов будут работать. От компилятора не требуется распознавать «поздние» комментарии как комментарии.
Лучший способ реализовать то, что вы хотите, - использовать макросы с переменными аргументами в C99 (или, возможно, с помощью расширений компилятора).
С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
На некоторых компиляторах (включая MS VS2010) это будет работать,
#define CMT / ## /
, но нет грантов для всех компиляторов.
Не проверено: Редактировать: протестировано, используя его сейчас самостоятельно:)
#define DEBUG 1
#define printd(fmt,...) if(DEBUG)printf(fmt, __VA_ARGS__)
требует, чтобы вы не только определили DEBUG
, но и дали ему значение, отличное от нуля.
Приложение: также хорошо работает с std::cout
Как отметил Маккей, у вас возникнут проблемы, если вы просто попытаетесь заменить printd
на //
. Вместо этого вы можете использовать переменные макросы для замены printd
функцией, которая ничего не делает, как показано ниже.
#ifndef DEBUG
#define printd(...) do_nothing()
#else
#define printd(...) printf(__VA_ARGS__)
#endif
void do_nothing() { ; }
Использование отладчика, такого как GDB, также может помочь, но иногда достаточно быстрого printf
.
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.
Вы можете поместить весь свой отладочный вызов в функцию, вызвать ее printf_debug
и поместить DEBUG
внутрь этой функции.
Компилятор оптимизирует пустую функцию.
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"
Дело сделано. Не рекомендую. Нет времени проверять, но механизм примерно такой:
#define printd_CAT(x) x ## x
#ifndef DEBUG
#define printd printd_CAT(/)
#else
#define printd printf
#endif
Это работает, если ваш компилятор обрабатывает // комментарии в самом компиляторе (нет такой гарантии, как ANSI, что есть два прохода для комментариев / *).
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...