Упростите вызов и используйте препроцессор вашего компилятора, чтобы увидеть, что происходит:
#define q(k)main(){puts(#k"hello("#k")");}
q(argument)
Запуск gcc -E
, который дает вам:
main(){puts("argument""hello(""argument"")");}
Как видите,что происходит, так это то, что аргумент макроса q
преобразуется в строку (потому что используется как #k
- это иногда называют "stringification").Здесь нет никакой другой магии.