C ++, 205 179 байт
int main(){};static int c=1;
#define v(x) A##x
#define u(x) v(x)
#define z u(__LINE__)
#include <cstdio>
class z{public:z(){++c;};~z(){if(c){printf("%d %o %x",--c,c,c);c=0;}}}z;//
(Нет завершающего символа новой строки - при копировании первая строка копии и последняя строка оригинала должны совпадать)
По сути, это работает путем создания последовательности статических переменных, которые при построении увеличивают счетчик глобальной переменной. Затем, при уничтожении, если счетчик не равен 0, он делает все свои выходные данные и устанавливает счетчик в ноль.
Чтобы определить последовательность переменных без конфликтов имен, мы используем макрос, объясненный следующим образом:
#define v(x) A##x //This concatenates the string "A" with the input x.
#define u(x) v(x) //This slows down the preprocessor so it expands __LINE__ rather than yielding A__LINE__ as v(__LINE__) would do.
#define z u(__LINE__)//Gives a name which is unique to each line.
что в некоторой степени зависит от особенностей струнного процессора. Мы используем z
много раз для определения классов / переменных, которые не будут конфликтовать друг с другом при копировании на отдельные строки. Более того, определения, которые должны встречаться только один раз, помещаются в первую строку, которая закомментирована в копиях кода. #define
and #include
не заботятся о том, что они повторяются, поэтому не требуют специальной обработки.
Этот код также имеет неопределенное поведение в выражении:
printf("%d %o %x",--c,c,c)
так как нет точек последовательности, но с изменен и доступен. LLVM 6.0 выдает предупреждение, но компилирует его по желанию, которое --c
оценивается раньше c
. Можно было бы, за счет двух байтов, добавьте инструкцию --c;
перед выходами и изменения --c
в printf
к c
, что бы избавиться от предупреждения.
Заменено std::cout
с printf
экономией 26 байтами благодаря предложению моего брата.
1 01 0x1
? (Включает префиксы)