Под Хабракатом небольшой этюд позволяющий писать маленькие или большие приложения, которые содержат в себе свой же код и выглядят при этом почти адекватно.
Как видно из исходника, явно списать код нужно только из «шапки», потому что все что находится в REPEAT-блоке будет автоматически застринговано и сохранено.
Сам макрос REPEAT устроен следующим образом: он принимает переменное число аргументов (чтоб не боятся запятых), затем «стрингует» то что ему передали, а затем еще раз повторяет то что ему передали, но на этот раз без кавычек (чтоб сохранить функционал).
Вот что получается после препроцессинга:
Признаться честно, я код изменил и привел в читаемый вид, потому что препроцессор почти все лепит в одну строчку. Тем не менее кроме переносов и лишних кавычек все на своих местах.
После запуска в stdout будет выведен функционально-идентичный исходник. Оформление только слегка помнется.
PS #include можно внести в REPEAT-блок, тогда его можно будет не писать явно в строке.
#include <stdio.h>
#define REPEAT(...) #__VA_ARGS__;__VA_ARGS__
char * ref = REPEAT(
int main()
{
printf("#include <stdio.h>\n"
"#define REPEAT(...) #__VA_ARGS__;__VA_ARGS__\n"
"char * ref = REPEAT(%s)", ref);
return 0;
}
)
Как видно из исходника, явно списать код нужно только из «шапки», потому что все что находится в REPEAT-блоке будет автоматически застринговано и сохранено.
Сам макрос REPEAT устроен следующим образом: он принимает переменное число аргументов (чтоб не боятся запятых), затем «стрингует» то что ему передали, а затем еще раз повторяет то что ему передали, но на этот раз без кавычек (чтоб сохранить функционал).
Вот что получается после препроцессинга:
g++ -E main.cpp
char * ref =
"int main()"
"{"
" printf(\"#include <stdio.h>\\n\""
" \"#define REPEAT(...) #__VA_ARGS__;__VA_ARGS__\\n\""
" \"char * ref = REPEAT(%s)\", ref);"
" return 0;"
"}";
int main()
{
printf("#include <stdio.h>\n"
"#define REPEAT(...) #__VA_ARGS__;__VA_ARGS__\n"
"char * ref = REPEAT(%s)", ref);
return 0;
}
Признаться честно, я код изменил и привел в читаемый вид, потому что препроцессор почти все лепит в одну строчку. Тем не менее кроме переносов и лишних кавычек все на своих местах.
После запуска в stdout будет выведен функционально-идентичный исходник. Оформление только слегка помнется.
PS #include можно внести в REPEAT-блок, тогда его можно будет не писать явно в строке.