Lo que se suele hacer es proveer a la función de una dirección donde almacenar la cadena a retornar (es decir, pasarle como argumento un puntero a char o un array de chars). Otra posibilidad es que la función reserve memoria dinámica para la cadena y retorne un puntero a la misma (el programa tendrá que ocuparse de liberar esa memoria oportunamente). También se puede retornar un puntero a un array de caracteres local a la función, siempre que sea 'static' (de otro modo, desaparece al terminar la función).
G