diff --git a/common/include/villas/utils.h b/common/include/villas/utils.h
index d70685c45..3a928d3d4 100644
--- a/common/include/villas/utils.h
+++ b/common/include/villas/utils.h
@@ -196,9 +196,8 @@ char * strcatf(char **dest, const char *fmt, ...)
 char * vstrcatf(char **dest, const char *fmt, va_list va)
 	__attribute__ ((format(printf, 2, 0)));
 
-/** Format string like strcatf() just starting with empty string */
-#define strf(fmt, ...) strcatf(&(char *) { NULL }, fmt, ##__VA_ARGS__)
-#define vstrf(fmt, va) vstrcatf(&(char *) { NULL }, fmt, va)
+char * strf(const char *fmt, ...);
+char * vstrf(const char *fmt, va_list va);
 
 /** Allocate and initialize memory. */
 void * alloc(size_t bytes);
diff --git a/common/lib/utils.c b/common/lib/utils.c
index 6b911002e..2bf46b4c2 100644
--- a/common/lib/utils.c
+++ b/common/lib/utils.c
@@ -91,6 +91,27 @@ char * vstrcatf(char **dest, const char *fmt, va_list ap)
 	return *dest;
 }
 
+char * strf(const char *fmt, ...)
+{
+	char *buf = NULL;
+
+	va_list ap;
+	va_start(ap, fmt);
+	vstrcatf(&buf, fmt, ap);
+	va_end(ap);
+
+	return buf;
+}
+
+char * vstrf(const char *fmt, va_list va)
+{
+	char *buf = NULL;
+
+	vstrcatf(&buf, fmt, va);
+
+	return buf;
+}
+
 void * alloc(size_t bytes)
 {
 	void *p = malloc(bytes);