diff --git a/common b/common
index a72a0e23a..a4dc8b8ca 160000
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit a72a0e23ab81dd7789aa723065b517c47fa0330b
+Subproject commit a4dc8b8ca7ad7e7bde055fc1b051218d24381ceb
diff --git a/include/villas/format_type.h b/include/villas/format_type.h
index f884002c7..c8771e9ae 100644
--- a/include/villas/format_type.h
+++ b/include/villas/format_type.h
@@ -89,12 +89,12 @@ struct format_type {
 	 * Low-level interface
 	 */
 
-	/** @see format_type_sscan */
-	int (*sscan)(struct io *io, const char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt);
-
 	/** @see format_type_sprint */
 	int (*sprint)(struct io *io, char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt);
 
+	/** @see format_type_sscan */
+	int (*sscan)(struct io *io, const char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt);
+
 	/** @} */
 
 	size_t size;				/**< Number of bytes to allocate for io::_vd */
diff --git a/include/villas/formats/msg_format.h b/include/villas/formats/msg_format.h
index 26176a3eb..2cf3025f9 100644
--- a/include/villas/formats/msg_format.h
+++ b/include/villas/formats/msg_format.h
@@ -48,10 +48,10 @@ extern "C" {
 
 /** Initialize a message with default values */
 #define MSG_INIT(len, seq) (struct msg) {\
-	.version  = MSG_VERSION,	\
 	.type     = MSG_TYPE_DATA,	\
-	.length   = len,	 	\
-	.sequence = seq,		\
+	.version  = MSG_VERSION,	\
+	.length   = (uint16_t) (len),	\
+	.sequence = (uint32_t) (seq),	\
 }
 
 /** The timestamp of a message in struct timespec format */
diff --git a/include/villas/mapping.h b/include/villas/mapping.h
index 9515da8f0..3505f2531 100644
--- a/include/villas/mapping.h
+++ b/include/villas/mapping.h
@@ -65,7 +65,7 @@ struct mapping_entry {
 	 * A value of 0 indicates that all remaining values starting from the offset of a sample should be mapped.
 	 */
 	int length;
-	int offset;			/**< Offset of this mapping entry within sample::data */
+	unsigned offset;			/**< Offset of this mapping entry within sample::data */
 
 	union {
 		struct {
diff --git a/include/villas/memory/ib.h b/include/villas/memory/ib.h
index dff44cb25..049ac863a 100644
--- a/include/villas/memory/ib.h
+++ b/include/villas/memory/ib.h
@@ -21,11 +21,21 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *********************************************************************************/
 
+#pragma once
+
 #include <villas/node.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct memory_ib {
     struct ibv_pd *pd;
     struct memory_type *parent;
 };
 
 struct ibv_mr * memory_ib_get_mr(void *ptr);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/include/villas/node/config.h.in b/include/villas/node/config.h.in
index 9059ee554..7e7884804 100644
--- a/include/villas/node/config.h.in
+++ b/include/villas/node/config.h.in
@@ -30,7 +30,7 @@
 
 /** Default number of values in a sample */
 #define DEFAULT_SAMPLE_LENGTH	64
-#define DEFAULT_QUEUE_LENGTH	1024
+#define DEFAULT_QUEUE_LENGTH	1024u
 
 /** Number of hugepages which are requested from the the kernel.
  * @see https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt */
diff --git a/include/villas/node_direction.h b/include/villas/node_direction.h
index 1fd86ccfb..48a8ee289 100644
--- a/include/villas/node_direction.h
+++ b/include/villas/node_direction.h
@@ -33,6 +33,10 @@
 #include <villas/common.h>
 #include <villas/list.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* Forward declarations */
 struct node;
 
@@ -47,7 +51,7 @@ struct node_direction {
 
 	int enabled;
 	int builtin;		/**< This node should use built-in hooks by default. */
-	int vectorize;		/**< Number of messages to send / recv at once (scatter / gather) */
+	unsigned vectorize;		/**< Number of messages to send / recv at once (scatter / gather) */
 
 	struct vlist hooks;	/**< List of read / write hooks (struct hook). */
 	struct vlist signals;	/**< Signal description. */
@@ -72,3 +76,7 @@ int node_direction_destroy(struct node_direction *nd, struct node *n);
 struct vlist * node_direction_get_signals(struct node_direction *nd);
 
 /** @} */
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/include/villas/node_type.h b/include/villas/node_type.h
index b9639123f..d1729f179 100644
--- a/include/villas/node_type.h
+++ b/include/villas/node_type.h
@@ -47,7 +47,7 @@ enum node_type_flags {
 
 /** C++ like vtable construct for node_types */
 struct node_type {
-	int vectorize;			/**< Maximal vector length supported by this node type. Zero is unlimited. */
+	unsigned vectorize;			/**< Maximal vector length supported by this node type. Zero is unlimited. */
 	int flags;
 
 	enum state state;		/**< State of this node-type. */
diff --git a/include/villas/nodes/stats.h b/include/villas/nodes/stats.hpp
similarity index 100%
rename from include/villas/nodes/stats.h
rename to include/villas/nodes/stats.hpp
diff --git a/include/villas/path.h b/include/villas/path.h
index 7f8083672..578397c91 100644
--- a/include/villas/path.h
+++ b/include/villas/path.h
@@ -81,8 +81,8 @@ struct path {
 	int poll;			/**< Weather or not to use poll(2). */
 	int reverse;			/**< This path as a matching reverse path. */
 	int builtin;			/**< This path should use built-in hooks by default. */
-	int queuelen;			/**< The queue length for each path_destination::queue */
 	int original_sequence_no;       /**< Use original source sequence number when multiplexing */
+	unsigned queuelen;			/**< The queue length for each path_destination::queue */
 
 	char *_name;			/**< Singleton: A string which is used to print this path to screen. */
 
diff --git a/include/villas/signal.h b/include/villas/signal.h
index 2dba077f6..6fa7dbd5a 100644
--- a/include/villas/signal.h
+++ b/include/villas/signal.h
@@ -110,7 +110,7 @@ int signal_list_destroy(struct vlist *list);
 int signal_list_parse(struct vlist *list, json_t *cfg);
 int signal_list_generate(struct vlist *list, unsigned len, enum signal_type fmt);
 int signal_list_generate2(struct vlist *list, const char *dt);
-void signal_list_dump(const struct vlist *list, const union signal_data *data, int len);
+void signal_list_dump(const struct vlist *list, const union signal_data *data, unsigned len);
 int signal_list_copy(struct vlist *dst, const struct vlist *src);
 
 enum signal_type signal_type_from_str(const char *str);
diff --git a/include/villas/stats.h b/include/villas/stats.h
index 10782b161..448a56349 100644
--- a/include/villas/stats.h
+++ b/include/villas/stats.h
@@ -27,7 +27,7 @@
 #include <jansson.h>
 
 #include <villas/common.h>
-#include <villas/hist.h>
+#include <villas/hist.hpp>
 #include <villas/signal.h>
 
 #ifdef __cplusplus
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index bdacb9737..bba1d3745 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -42,34 +42,33 @@ endif()
 set(LIB_SRC
     config_helper.cpp
     config.cpp
-    mapping.c
-    memory.c
-    memory/heap.c
-    memory/hugepage.c
-    memory/managed.c
-    node_direction.c
-    node_type.c
-    node.c
-    path_destination.c
-    path_source.c
-    path.c
-    plugin.c
-    pool.c
-    queue_signalled.c
-    queue.c
-    sample.c
-    shmem.c
-    signal.c
-    stats.c
+    mapping.cpp
+    memory.cpp
+    memory/heap.cpp
+    memory/hugepage.cpp
+    memory/managed.cpp
+    node_direction.cpp
+    node_type.cpp
+    node.cpp
+    path_destination.cpp
+    path_source.cpp
+    path.cpp
+    plugin.cpp
+    pool.cpp
+    queue_signalled.cpp
+    queue.cpp
+    sample.cpp
+    shmem.cpp
+    signal.cpp
+    stats.cpp
     super_node.cpp
-    socket_addr.c
-    io.c
-    format_type.c
-
+    socket_addr.cpp
+    io.cpp
+    format_type.cpp
 )
 
 if(WITH_NODE_INFINIBAND)
-    list(APPEND LIB_SRC memory/ib.c)
+    list(APPEND LIB_SRC memory/ib.cpp)
 endif()
 
 add_subdirectory(nodes)
@@ -114,10 +113,10 @@ endif()
 # libnl3 is optional but required for network emulation and IRQ pinning
 if(LIBNL3_ROUTE_FOUND)
     list(APPEND LIB_SRC
-        kernel/nl.c
-        kernel/tc.c
-        kernel/tc_netem.c
-        kernel/if.c
+        kernel/nl.cpp
+        kernel/tc.cpp
+        kernel/tc_netem.cpp
+        kernel/if.cpp
     )
 
     list(APPEND INCLUDE_DIRS ${LIBNL3_ROUTE_INCLUDE_DIRS})
diff --git a/lib/config_helper.cpp b/lib/config_helper.cpp
index 97ec9d3b8..5c769f159 100644
--- a/lib/config_helper.cpp
+++ b/lib/config_helper.cpp
@@ -213,7 +213,7 @@ void json_object_extend_key_value(json_t *obj, const char *key, const char *valu
 		}
 
 		key1 = key2;
-		key2 = strtok_r(NULL, ".", &lasts);
+		key2 = strtok_r(nullptr, ".", &lasts);
  	}
 
 	/* Try to parse as integer */
@@ -349,7 +349,7 @@ int json_object_extend_str(json_t *obj, const char *str)
 	cpy = strdup(str);
 
 	key = strtok_r(cpy, "=", &lasts);
-	value = strtok_r(NULL, "", &lasts);
+	value = strtok_r(nullptr, "", &lasts);
 
 	if (!key || !value)
 		return -1;
diff --git a/lib/format_type.c b/lib/format_type.cpp
similarity index 98%
rename from lib/format_type.c
rename to lib/format_type.cpp
index c9d191c82..0b5e93e66 100644
--- a/lib/format_type.c
+++ b/lib/format_type.cpp
@@ -32,7 +32,7 @@ struct format_type * format_type_lookup(const char *name)
 
 	p = plugin_lookup(PLUGIN_TYPE_FORMAT, name);
 	if (!p)
-		return NULL;
+		return nullptr;
 
 	return &p->format;
 }
diff --git a/lib/formats/CMakeLists.txt b/lib/formats/CMakeLists.txt
index 5bc3eba3f..d8e3689cb 100644
--- a/lib/formats/CMakeLists.txt
+++ b/lib/formats/CMakeLists.txt
@@ -46,7 +46,7 @@ if(DEFINED PROTOBUFC_COMPILER AND PROTOBUFC_FOUND)
     )
 
     list(APPEND FORMAT_SRC
-        protobuf.c
+        protobuf.cpp
         ${CMAKE_CURRENT_BINARY_DIR}/villas.pb-c.c
     )
 
@@ -61,13 +61,13 @@ if(DEFINED PROTOBUFC_COMPILER AND PROTOBUFC_FOUND)
 endif()
 
 list(APPEND FORMAT_SRC
-    json.c
-    json_reserve.c
-    villas_binary.c
-    villas_human.c
-    csv.c
-    raw.c
-    msg.c
+    json.cpp
+    json_reserve.cpp
+    villas_binary.cpp
+    villas_human.cpp
+    csv.cpp
+    raw.cpp
+    msg.cpp
 )
 
 add_library(formats STATIC ${FORMAT_SRC})
diff --git a/lib/formats/csv.c b/lib/formats/csv.cpp
similarity index 94%
rename from lib/formats/csv.c
rename to lib/formats/csv.cpp
index 428fc98fc..fcb5e5cff 100644
--- a/lib/formats/csv.c
+++ b/lib/formats/csv.cpp
@@ -58,8 +58,8 @@ static size_t csv_sprint_single(struct io *io, char *buf, size_t len, const stru
 	}
 
 	if (io->flags & SAMPLE_HAS_DATA) {
-		for (int i = 0; i < smp->length; i++) {
-			sig = vlist_at_safe(smp->signals, i);
+		for (unsigned i = 0; i < smp->length; i++) {
+			sig = (struct signal *) vlist_at_safe(smp->signals, i);
 			if (!sig)
 				break;
 
@@ -75,10 +75,13 @@ static size_t csv_sprint_single(struct io *io, char *buf, size_t len, const stru
 
 static size_t csv_sscan_single(struct io *io, const char *buf, size_t len, struct sample *smp)
 {
-	int ret, i = 0;
+	int ret;
+	unsigned i = 0;
 	const char *ptr = buf;
 	char *end;
 
+	double offset __attribute__((unused));
+
 	smp->flags = 0;
 	smp->signals = io->signals;
 
@@ -96,7 +99,7 @@ static size_t csv_sscan_single(struct io *io, const char *buf, size_t len, struc
 
 	smp->flags |= SAMPLE_HAS_TS_ORIGIN;
 
-	double offset __attribute__((unused)) = strtof(ptr, &end);
+	offset = strtof(ptr, &end);
 	if (end == ptr || *end == io->delimiter)
 		goto out;
 
@@ -134,7 +137,7 @@ out:	if (*end == io->delimiter)
 
 int csv_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt)
 {
-	int i;
+	unsigned i;
 	size_t off = 0;
 
 	for (i = 0; i < cnt && off < len; i++)
@@ -148,7 +151,7 @@ int csv_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp
 
 int csv_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt)
 {
-	int i;
+	unsigned i;
 	size_t off = 0;
 
 	for (i = 0; i < cnt && off < len; i++)
@@ -175,7 +178,7 @@ void csv_header(struct io *io, const struct sample *smp)
 		fprintf(f, "sequence%c", io->separator);
 
 	if (io->flags & SAMPLE_HAS_DATA) {
-		for (int i = 0; i < smp->length; i++) {
+		for (unsigned i = 0; i < smp->length; i++) {
 			struct signal *sig = (struct signal *) vlist_at(smp->signals, i);
 
 			if (sig->name)
@@ -186,7 +189,7 @@ void csv_header(struct io *io, const struct sample *smp)
 			if (sig->unit)
 				fprintf(f, "[%s]", sig->unit);
 
-			if (i+1 < smp->length)
+			if (i + 1 < smp->length)
 				fprintf(f, "%c", io->separator);
 		}
 	}
@@ -199,9 +202,9 @@ static struct plugin p1 = {
 	.description = "Tabulator-separated values",
 	.type = PLUGIN_TYPE_FORMAT,
 	.format = {
+		.header	= csv_header,
 		.sprint	= csv_sprint,
 		.sscan	= csv_sscan,
-		.header	= csv_header,
 		.size 	= 0,
 		.flags	= IO_NEWLINES |
 		          SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA,
@@ -214,9 +217,9 @@ static struct plugin p2 = {
 	.description = "Comma-separated values",
 	.type = PLUGIN_TYPE_FORMAT,
 	.format = {
+		.header	= csv_header,
 		.sprint	= csv_sprint,
 		.sscan	= csv_sscan,
-		.header	= csv_header,
 		.size 	= 0,
 		.flags	= IO_NEWLINES |
 		          SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA,
diff --git a/lib/formats/json.c b/lib/formats/json.cpp
similarity index 95%
rename from lib/formats/json.c
rename to lib/formats/json.cpp
index 99b65f941..cf3933ba4 100644
--- a/lib/formats/json.c
+++ b/lib/formats/json.cpp
@@ -46,7 +46,7 @@ static enum signal_type json_detect_format(json_t *val)
 			return SIGNAL_TYPE_COMPLEX; /* must be a complex number */
 
 		default:
-			return -1;
+			return SIGNAL_TYPE_INVALID;
 	}
 }
 
@@ -67,7 +67,8 @@ static int json_unpack_timestamps(json_t *json_ts, struct sample *smp)
 {
 	int ret;
 	json_error_t err;
-	json_t *json_ts_origin = NULL, *json_ts_received = NULL;
+	json_t *json_ts_origin = nullptr;
+	json_t *json_ts_received = nullptr;
 
 	json_unpack_ex(json_ts, &err, 0, "{ s?: o, s?: o }",
 		"origin",   &json_ts_origin,
@@ -109,7 +110,7 @@ static int json_pack_sample(struct io *io, json_t **j, struct sample *smp)
 	if (io->flags & smp->flags & SAMPLE_HAS_DATA) {
 		json_t *json_data = json_array();
 
-		for (int i = 0; i < smp->length; i++) {
+		for (unsigned i = 0; i < smp->length; i++) {
 			enum signal_type fmt = sample_format(smp, i);
 
 			json_t *json_value;
@@ -153,7 +154,7 @@ static int json_pack_samples(struct io *io, json_t **j, struct sample *smps[], u
 	int ret;
 	json_t *json_smps = json_array();
 
-	for (int i = 0; i < cnt; i++) {
+	for (unsigned i = 0; i < cnt; i++) {
 		json_t *json_smp;
 
 		ret = json_pack_sample(io, &json_smp, smps[i]);
@@ -172,7 +173,7 @@ static int json_unpack_sample(struct io *io, json_t *json_smp, struct sample *sm
 {
 	int ret;
 	json_error_t err;
-	json_t *json_data, *json_value, *json_ts = NULL;
+	json_t *json_data, *json_value, *json_ts = nullptr;
 	size_t i;
 	int64_t sequence = -1;
 
@@ -206,7 +207,7 @@ static int json_unpack_sample(struct io *io, json_t *json_smp, struct sample *sm
 		if (i >= smp->capacity)
 			break;
 
-		struct signal *sig = vlist_at_safe(smp->signals, i);
+		struct signal *sig = (struct signal *) vlist_at_safe(smp->signals, i);
 		if (!sig)
 			return -1;
 
@@ -296,7 +297,8 @@ int json_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struc
 
 int json_print(struct io *io, struct sample *smps[], unsigned cnt)
 {
-	int ret, i;
+	int ret;
+	unsigned i;
 	json_t *json;
 
 	FILE *f = io_stream_output(io);
@@ -320,7 +322,8 @@ int json_print(struct io *io, struct sample *smps[], unsigned cnt)
 
 int json_scan(struct io *io, struct sample *smps[], unsigned cnt)
 {
-	int i, ret;
+	int ret;
+	unsigned i;
 	json_t *json;
 	json_error_t err;
 
@@ -349,13 +352,13 @@ static struct plugin p = {
 	.description = "Javascript Object Notation",
 	.type = PLUGIN_TYPE_FORMAT,
 	.format = {
-		.scan	= json_scan,
 		.print	= json_print,
-		.sscan	= json_sscan,
+		.scan	= json_scan,
 		.sprint	= json_sprint,
+		.sscan	= json_sscan,
 		.size = 0,
-		.delimiter = '\n',
-		.flags = SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA
+		.flags = SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA,
+		.delimiter = '\n'
 	},
 };
 
diff --git a/lib/formats/json_reserve.c b/lib/formats/json_reserve.cpp
similarity index 93%
rename from lib/formats/json_reserve.c
rename to lib/formats/json_reserve.cpp
index 09acb16bd..75f350604 100644
--- a/lib/formats/json_reserve.c
+++ b/lib/formats/json_reserve.cpp
@@ -37,7 +37,8 @@ static int json_reserve_pack_sample(struct io *io, json_t **j, struct sample *sm
 {
 	json_error_t err;
 	json_t *json_data, *json_name, *json_unit, *json_value;
-	json_t *json_created = NULL, *json_sequence = NULL;
+	json_t *json_created = nullptr;
+	json_t *json_sequence = nullptr;
 
 	if (smp->flags & SAMPLE_HAS_TS_ORIGIN)
 		json_created = json_integer(time_to_double(&smp->ts.origin) * 1e3);
@@ -47,10 +48,10 @@ static int json_reserve_pack_sample(struct io *io, json_t **j, struct sample *sm
 
 	json_data = json_array();
 
-	for (int i = 0; i < smp->length; i++) {
+	for (unsigned i = 0; i < smp->length; i++) {
 		struct signal *sig;
 
-		sig = vlist_at_safe(smp->signals, i);
+		sig = (struct signal *) vlist_at_safe(smp->signals, i);
 		if (!sig)
 			return -1;
 
@@ -66,7 +67,7 @@ static int json_reserve_pack_sample(struct io *io, json_t **j, struct sample *sm
 		if (sig->unit)
 			json_unit = json_string(sig->unit);
 		else
-			json_unit = NULL;
+			json_unit = nullptr;
 
 		json_value = json_pack_ex(&err, 0, "{ s: o, s: f }",
 			"name", json_name,
@@ -93,7 +94,7 @@ static int json_reserve_pack_sample(struct io *io, json_t **j, struct sample *sm
 	*j = json_pack_ex(&err, 0, "{ s: o }",
 		"measurements", json_data
 	);
-	if (*j == NULL)
+	if (*j == nullptr)
 		return -1;
 #if 0
 #ifdef JSON_RESERVE_INTEGER_TARGET
@@ -123,8 +124,8 @@ static int json_reserve_unpack_sample(struct io *io, json_t *json_smp, struct sa
 	int ret, idx;
 	double created = -1;
 	json_error_t err;
-	json_t *json_value, *json_data = NULL;
-	json_t *json_origin = NULL, *json_target = NULL;
+	json_t *json_value, *json_data = nullptr;
+	json_t *json_origin = nullptr, *json_target = nullptr;
 	size_t i;
 
 	ret = json_unpack_ex(json_smp, &err, 0, "{ s?: o, s?: o, s?: o, s?: o }",
@@ -172,7 +173,7 @@ static int json_reserve_unpack_sample(struct io *io, json_t *json_smp, struct sa
 	smp->length = 0;
 
 	json_array_foreach(json_data, i, json_value) {
-		const char *name, *unit = NULL;
+		const char *name, *unit = nullptr;
 		double value;
 
 		ret = json_unpack_ex(json_value, &err, 0, "{ s: s, s?: s, s: F, s?: F }",
@@ -199,10 +200,13 @@ static int json_reserve_unpack_sample(struct io *io, json_t *json_smp, struct sa
 				continue;
 		}
 
-		if (idx < smp->capacity) {
+		if (idx < 0)
+			return -1;
+
+		if (idx < (int) smp->capacity) {
 			smp->data[idx].f = value;
 
-			if (idx >= smp->length)
+			if (idx >= (int) smp->length)
 				smp->length = idx + 1;
 		}
 	}
@@ -271,7 +275,8 @@ int json_reserve_sscan(struct io *io, const char *buf, size_t len, size_t *rbyte
 
 int json_reserve_print(struct io *io, struct sample *smps[], unsigned cnt)
 {
-	int ret, i;
+	int ret;
+	unsigned i;
 	json_t *json;
 
 	FILE *f = io_stream_output(io);
@@ -295,7 +300,8 @@ int json_reserve_print(struct io *io, struct sample *smps[], unsigned cnt)
 
 int json_reserve_scan(struct io *io, struct sample *smps[], unsigned cnt)
 {
-	int i, ret;
+	int ret;
+	unsigned i;
 	json_t *json;
 	json_error_t err;
 
@@ -322,10 +328,10 @@ static struct plugin p = {
 	.description = "RESERVE JSON format",
 	.type = PLUGIN_TYPE_FORMAT,
 	.format = {
-		.scan	= json_reserve_scan,
 		.print	= json_reserve_print,
-		.sscan	= json_reserve_sscan,
+		.scan	= json_reserve_scan,
 		.sprint	= json_reserve_sprint,
+		.sscan	= json_reserve_sscan,
 		.size = 0
 	},
 };
diff --git a/lib/formats/msg.c b/lib/formats/msg.cpp
similarity index 92%
rename from lib/formats/msg.c
rename to lib/formats/msg.cpp
index 4f9d7be76..a53de7fbb 100644
--- a/lib/formats/msg.c
+++ b/lib/formats/msg.cpp
@@ -86,8 +86,8 @@ int msg_to_sample(struct msg *msg, struct sample *smp, struct vlist *signals)
 	smp->sequence = msg->sequence;
 	smp->ts.origin = MSG_TS(msg);
 
-	for (int i = 0; i < MIN(smp->length, vlist_length(signals)); i++) {
-		struct signal *sig = vlist_at(signals, i);
+	for (unsigned i = 0; i < MIN(smp->length, vlist_length(signals)); i++) {
+		struct signal *sig = (struct signal *) vlist_at(signals, i);
 
 		switch (sig->type) {
 			case SIGNAL_TYPE_FLOAT:
@@ -113,8 +113,8 @@ int msg_from_sample(struct msg *msg, struct sample *smp, struct vlist *signals)
 	msg->ts.sec  = smp->ts.origin.tv_sec;
 	msg->ts.nsec = smp->ts.origin.tv_nsec;
 
-	for (int i = 0; i < smp->length; i++) {
-		struct signal *sig = vlist_at(signals, i);
+	for (unsigned i = 0; i < smp->length; i++) {
+		struct signal *sig = (struct signal *) vlist_at(signals, i);
 
 		switch (sig->type) {
 			case SIGNAL_TYPE_FLOAT:
diff --git a/lib/formats/protobuf.c b/lib/formats/protobuf.cpp
similarity index 84%
rename from lib/formats/protobuf.c
rename to lib/formats/protobuf.cpp
index 72c604cd2..d60d992de 100644
--- a/lib/formats/protobuf.c
+++ b/lib/formats/protobuf.cpp
@@ -54,14 +54,14 @@ int protobuf_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct
 {
 	unsigned psz;
 
-	Villas__Node__Message *pb_msg = alloc(sizeof(Villas__Node__Message));
+	Villas__Node__Message *pb_msg = (Villas__Node__Message *) alloc(sizeof(Villas__Node__Message));
 	villas__node__message__init(pb_msg);
 
 	pb_msg->n_samples = cnt;
-	pb_msg->samples = alloc(pb_msg->n_samples * sizeof(Villas__Node__Sample *));
+	pb_msg->samples = (Villas__Node__Sample **) alloc(pb_msg->n_samples * sizeof(Villas__Node__Sample *));
 
 	for (unsigned i = 0; i < pb_msg->n_samples; i++) {
-		Villas__Node__Sample *pb_smp = pb_msg->samples[i] = alloc(sizeof(Villas__Node__Sample));
+		Villas__Node__Sample *pb_smp = pb_msg->samples[i] = (Villas__Node__Sample *) alloc(sizeof(Villas__Node__Sample));
 		villas__node__sample__init(pb_smp);
 
 		struct sample *smp = smps[i];
@@ -74,7 +74,7 @@ int protobuf_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct
 		}
 
 		if (io->flags & smp->flags & SAMPLE_HAS_TS_ORIGIN) {
-			pb_smp->timestamp = alloc(sizeof(Villas__Node__Timestamp));
+			pb_smp->timestamp = (Villas__Node__Timestamp *) alloc(sizeof(Villas__Node__Timestamp));
 			villas__node__timestamp__init(pb_smp->timestamp);
 
 			pb_smp->timestamp->sec = smp->ts.origin.tv_sec;
@@ -82,10 +82,10 @@ int protobuf_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct
 		}
 
 		pb_smp->n_values = smp->length;
-		pb_smp->values = alloc(pb_smp->n_values * sizeof(Villas__Node__Value *));
+		pb_smp->values = (Villas__Node__Value **) alloc(pb_smp->n_values * sizeof(Villas__Node__Value *));
 
 		for (unsigned j = 0; j < pb_smp->n_values; j++) {
-			Villas__Node__Value *pb_val = pb_smp->values[j] = alloc(sizeof(Villas__Node__Value));
+			Villas__Node__Value *pb_val = pb_smp->values[j] = (Villas__Node__Value *) alloc(sizeof(Villas__Node__Value));
 			villas__node__value__init(pb_val);
 
 			enum signal_type fmt = sample_format(smp, j);
@@ -107,7 +107,7 @@ int protobuf_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct
 
 				case SIGNAL_TYPE_COMPLEX:
 					pb_val->value_case = VILLAS__NODE__VALUE__VALUE_Z;
-					pb_val->z = alloc(sizeof(Villas__Node__Complex));
+					pb_val->z = (Villas__Node__Complex *) alloc(sizeof(Villas__Node__Complex));
 
 					villas__node__complex__init(pb_val->z);
 
@@ -128,14 +128,14 @@ int protobuf_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct
 		goto out;
 
 	villas__node__message__pack(pb_msg, (uint8_t *) buf);
-	villas__node__message__free_unpacked(pb_msg, NULL);
+	villas__node__message__free_unpacked(pb_msg, nullptr);
 
 	*wbytes = psz;
 
 	return cnt;
 
 out:
-	villas__node__message__free_unpacked(pb_msg, NULL);
+	villas__node__message__free_unpacked(pb_msg, nullptr);
 
 	return -1;
 }
@@ -145,7 +145,7 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s
 	unsigned i, j;
 	Villas__Node__Message *pb_msg;
 
-	pb_msg = villas__node__message__unpack(NULL, len, (uint8_t *) buf);
+	pb_msg = villas__node__message__unpack(nullptr, len, (uint8_t *) buf);
 	if (!pb_msg)
 		return -1;
 
@@ -200,7 +200,7 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s
 					break;
 
 				case SIGNAL_TYPE_COMPLEX:
-					smp->data[j].z = CMPLXF(pb_val->z->real, pb_val->z->imag);
+					smp->data[j].z = pb_val->z->real + _Complex_I * pb_val->z->imag;
 					break;
 
 				default: { }
@@ -216,7 +216,7 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s
 	if (rbytes)
 		*rbytes = villas__node__message__get_packed_size(pb_msg);
 
-	villas__node__message__free_unpacked(pb_msg, NULL);
+	villas__node__message__free_unpacked(pb_msg, nullptr);
 
 	return i;
 }
diff --git a/lib/formats/raw.c b/lib/formats/raw.cpp
similarity index 74%
rename from lib/formats/raw.c
rename to lib/formats/raw.cpp
index b68d23162..48d33acab 100644
--- a/lib/formats/raw.c
+++ b/lib/formats/raw.cpp
@@ -56,20 +56,20 @@ int raw_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp
 	int o = 0;
 	size_t nlen;
 
-	int8_t     *i8  =  (void *) buf;
-	int16_t    *i16 =  (void *) buf;
-	int32_t    *i32 =  (void *) buf;
-	int64_t    *i64 =  (void *) buf;
-	float      *f32 =  (void *) buf;
-	double     *f64 =  (void *) buf;
+	int8_t     *i8  =  (int8_t *) buf;
+	int16_t    *i16 =  (int16_t *) buf;
+	int32_t    *i32 =  (int32_t *) buf;
+	int64_t    *i64 =  (int64_t *) buf;
+	float      *f32 =  (float *) buf;
+	double     *f64 =  (double *) buf;
 #ifdef HAS_128BIT
-	__int128   *i128 = (void *) buf;
-	__float128 *f128 = (void *) buf;
+	__int128   *i128 = (__int128 *) buf;
+	__float128 *f128 = (__float128 *) buf;
 #endif
 
 	int bits = 1 << (io->flags >> 24);
 
-	for (int i = 0; i < cnt; i++) {
+	for (unsigned i = 0; i < cnt; i++) {
 		struct sample *smp = smps[i];
 
 		/* First three values are sequence, seconds and nano-seconds timestamps
@@ -117,7 +117,7 @@ int raw_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp
 			}
 		}
 
-		for (int j = 0; j < smp->length; j++) {
+		for (unsigned j = 0; j < smp->length; j++) {
 			enum signal_type fmt = sample_format(smp, j);
 			union signal_data *data = &smp->data[j];
 
@@ -129,11 +129,22 @@ int raw_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp
 			switch (fmt) {
 				case SIGNAL_TYPE_FLOAT:
 					switch (bits) {
-						case  8:  i8 [o++]  = -1; break; /* Not supported */
-						case 16:  i16[o++]  = -1; break; /* Not supported */
+						case 8:
+							i8 [o++] = -1;
+							break; /* Not supported */
+
+						case 16:
+							i16[o++] = -1;
+							break; /* Not supported */
+
+						case 32:
+							f32[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN,  32, (float) data->f);
+							break;
+
+						case 64:
+							f64[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN,  64, data->f);
+							break;
 
-						case 32:  f32[o++]  = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN,  32, data->f); break;
-						case 64:  f64[o++]  = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN,  64, data->f); break;
 #ifdef HAS_128BIT
 						case 128: f128[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 128, data->f); break;
 #endif
@@ -142,42 +153,82 @@ int raw_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp
 
 				case SIGNAL_TYPE_INTEGER:
 					switch (bits) {
-						case  8:  i8 [o++]  =                                                 data->i;  break;
-						case 16:  i16[o++]  = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 16,  data->i); break;
-						case 32:  i32[o++]  = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 32,  data->i); break;
-						case 64:  i64[o++]  = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 64,  data->i); break;
+						case 8:
+							i8 [o++] = data->i;
+							break;
+
+						case 16:
+							i16[o++] = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 16,  data->i);
+							break;
+
+						case 32:
+							i32[o++] = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 32,  data->i);
+							break;
+
+						case 64:
+							i64[o++] = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 64,  data->i);
+							break;
+
 #ifdef HAS_128BIT
-						case 128: i128[o++] = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 128, data->i); break;
+						case 128:
+							i128[o++] = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 128, data->i);
+							break;
 #endif
 					}
 					break;
 
 				case SIGNAL_TYPE_BOOLEAN:
 					switch (bits) {
-						case  8:  i8 [o++]  =                                                 data->b ? 1 : 0;  break;
-						case 16:  i16[o++]  = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 16,  data->b ? 1 : 0); break;
-						case 32:  i32[o++]  = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 32,  data->b ? 1 : 0); break;
-						case 64:  i64[o++]  = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 64,  data->b ? 1 : 0); break;
+						case 8:
+							i8 [o++] = data->b ? 1 : 0; 
+							break;
+
+						case 16:
+							i16[o++] = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 16,  data->b ? 1 : 0);
+							break;
+
+						case 32:
+							i32[o++] = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 32,  data->b ? 1 : 0);
+							break;
+
+						case 64:
+							i64[o++] = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 64,  data->b ? 1 : 0);
+							break;
+
 #ifdef HAS_128BIT
-						case 128: i128[o++] = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 128, data->b ? 1 : 0); break;
+						case 128:
+							i128[o++] = SWAP_INT_HTOX(io->flags & RAW_BIG_ENDIAN, 128, data->b ? 1 : 0);
+							break;
 #endif
 					}
 					break;
 
 				case SIGNAL_TYPE_COMPLEX:
 					switch (bits) {
-						case  8:  i8 [o++]  = -1; /* Not supported */
-							  i8 [o++]  = -1; break;
-						case 16:  i16[o++]  = -1; /* Not supported */
-							  i16[o++]  = -1; break;
+						case  8:
+							i8 [o++]  = -1; /* Not supported */
+							i8 [o++]  = -1;
+							break;
 
-						case 32:  f32[o++]  = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN,  32, creal(data->z));
-							  f32[o++]  = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN,  32, cimag(data->z)); break;
-						case 64:  f64[o++]  = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN,  64, creal(data->z));
-							  f64[o++]  = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN,  64, cimag(data->z)); break;
+						case 16:
+							i16[o++]  = -1; /* Not supported */
+							i16[o++]  = -1;
+							break;
+
+						case 32:
+							f32[o++]  = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN,  32, (float) creal(data->z));
+							f32[o++]  = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN,  32, (float ) cimag(data->z));
+							break;
+
+						case 64:
+							f64[o++]  = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN,  64, creal(data->z));
+							f64[o++]  = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN,  64, cimag(data->z));
+							break;
 #ifdef HAS_128BIT
-						case 128: f128[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 128, creal(data->z);
-							  f128[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 128, cimag(data->z); break;
+						case 128:
+							f128[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 128, creal(data->z);
+							f128[o++] = SWAP_FLOAT_HTOX(io->flags & RAW_BIG_ENDIAN, 128, cimag(data->z);
+							break;
 #endif
 					}
 					break;
@@ -196,15 +247,15 @@ out:	if (wbytes)
 
 int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt)
 {
-	int8_t     *i8  =  (void *) buf;
-	int16_t    *i16 =  (void *) buf;
-	int32_t    *i32 =  (void *) buf;
-	int64_t    *i64 =  (void *) buf;
-	float      *f32 =  (void *) buf;
-	double     *f64 =  (void *) buf;
+	int8_t     *i8  =  (int8_t *)  buf;
+	int16_t    *i16 =  (int16_t *) buf;
+	int32_t    *i32 =  (int32_t *) buf;
+	int64_t    *i64 =  (int64_t *) buf;
+	float      *f32 =  (float *) buf;
+	double     *f64 =  (double *) buf;
 #ifdef HAS_128BIT
-	__int128   *i128 = (void *) buf;
-	__float128 *f128 = (void *) buf;
+	__int128   *i128 = (__int128 *) buf;
+	__float128 *f128 = (__float128 *) buf;
 #endif
 
 	/* The raw format can not encode multiple samples in one buffer
@@ -273,7 +324,7 @@ int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct
 
 	smp->signals = io->signals;
 
-	int i;
+	unsigned i;
 	for (i = 0; i < smp->capacity && o < nlen; i++) {
 		enum signal_type fmt = sample_format(smp, i);
 		union signal_data *data = &smp->data[i];
@@ -318,26 +369,21 @@ int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct
 
 			case SIGNAL_TYPE_COMPLEX:
 				switch (bits) {
-					case 8:  data->z = CMPLXF(-1, -1); o += 2; break; /* Not supported */
-					case 16: data->z = CMPLXF(-1, -1); o += 2; break; /* Not supported */
+					case 8:  data->z = -1 + _Complex_I * -1; o += 2; break; /* Not supported */
+					case 16: data->z = -1 + _Complex_I * -1; o += 2; break; /* Not supported */
 
-					case 32: data->z = CMPLXF(
-							SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 32, f32[o++]), /* real */
-							SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 32, f32[o++])  /* imag */
-					        );
+					case 32: data->z = SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 32, f32[o++])
+							+ _Complex_I * SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 32, f32[o++]);
+					        
 						break;
 
-					case 64: data->z = CMPLXF(
-							SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 64, f64[o++]), /* real */
-							SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 64, f64[o++])  /* imag */
-					        );
+					case 64: data->z = SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 64, f64[o++])
+							+ _Complex_I * SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 64, f64[o++]);
 						break;
 
 #if HAS_128BIT
-					case 128: data->z = CMPLXF(
-							SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 128, f128[o++]), /* real */
-							SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 128, f128[o++])  /* imag */
-					        );
+					case 128: data->z = SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 128, f128[o++])
+							+ _Complex_I * SWAP_FLOAT_XTOH(io->flags & RAW_BIG_ENDIAN, 128, f128[o++]);
 						break;
 #endif
 				}
@@ -368,10 +414,10 @@ static struct plugin i = {			\
 	.description = d,			\
 	.type = PLUGIN_TYPE_FORMAT,		\
 	.format = {				\
-		.flags = f | IO_HAS_BINARY_PAYLOAD |\
-			     SAMPLE_HAS_DATA,	\
 		.sprint = raw_sprint,		\
-		.sscan  = raw_sscan		\
+		.sscan  = raw_sscan,		\
+		.flags = f | IO_HAS_BINARY_PAYLOAD |\
+			     SAMPLE_HAS_DATA	\
 	}					\
 };						\
 REGISTER_PLUGIN(& i);
diff --git a/lib/formats/villas_binary.c b/lib/formats/villas_binary.cpp
similarity index 98%
rename from lib/formats/villas_binary.c
rename to lib/formats/villas_binary.cpp
index ead10dba2..e7530dfeb 100644
--- a/lib/formats/villas_binary.c
+++ b/lib/formats/villas_binary.cpp
@@ -32,7 +32,8 @@
 
 int villas_binary_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt)
 {
-	int ret, i = 0;
+	int ret;
+	unsigned i = 0;
 	char *ptr = buf;
 
 	for (i = 0; i < cnt; i++) {
@@ -63,7 +64,8 @@ int villas_binary_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, s
 
 int villas_binary_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt)
 {
-	int ret, i = 0, values;
+	int ret, values;
+	unsigned i = 0;
 	const char *ptr = buf;
 
 	if (len % 4 != 0) {
diff --git a/lib/formats/villas_human.c b/lib/formats/villas_human.cpp
similarity index 95%
rename from lib/formats/villas_human.c
rename to lib/formats/villas_human.cpp
index 8f036562f..2e42e83e4 100644
--- a/lib/formats/villas_human.c
+++ b/lib/formats/villas_human.cpp
@@ -57,8 +57,8 @@ static size_t villas_human_sprint_single(struct io *io, char *buf, size_t len, c
 	}
 
 	if (io->flags & SAMPLE_HAS_DATA) {
-		for (int i = 0; i < smp->length; i++) {
-			sig = vlist_at_safe(smp->signals, i);
+		for (unsigned i = 0; i < smp->length; i++) {
+			sig = (struct signal *) vlist_at_safe(smp->signals, i);
 			if (!sig)
 				break;
 
@@ -132,7 +132,7 @@ static size_t villas_human_sscan_single(struct io *io, const char *buf, size_t l
 			end++;
 	}
 
-	int i;
+	unsigned i;
 	for (ptr = end + 1, i = 0; i < smp->capacity; ptr = end + 1, i++) {
 
 		if (*end == io->delimiter)
@@ -166,7 +166,7 @@ out:	if (*end == io->delimiter)
 
 int villas_human_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct sample *smps[], unsigned cnt)
 {
-	int i;
+	unsigned i;
 	size_t off = 0;
 
 	for (i = 0; i < cnt && off < len; i++)
@@ -180,7 +180,7 @@ int villas_human_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, st
 
 int villas_human_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt)
 {
-	int i;
+	unsigned i;
 	size_t off = 0;
 
 	for (i = 0; i < cnt && off < len; i++)
@@ -208,7 +208,7 @@ void villas_human_header(struct io *io, const struct sample *smp)
 		fprintf(f, "(sequence)");
 
 	if (io->flags & SAMPLE_HAS_DATA) {
-		for (int i = 0; i < MIN(smp->length, vlist_length(smp->signals)); i++) {
+		for (unsigned i = 0; i < MIN(smp->length, vlist_length(smp->signals)); i++) {
 			struct signal *sig = (struct signal *) vlist_at(smp->signals, i);
 
 			if (sig->name)
@@ -229,13 +229,13 @@ static struct plugin p = {
 	.description = "VILLAS human readable format",
 	.type = PLUGIN_TYPE_FORMAT,
 	.format = {
+		.header = villas_human_header,
 		.sprint	= villas_human_sprint,
 		.sscan	= villas_human_sscan,
-		.header = villas_human_header,
 		.size	= 0,
 		.flags	= IO_NEWLINES | SAMPLE_HAS_TS_ORIGIN | SAMPLE_HAS_SEQUENCE | SAMPLE_HAS_DATA,
-		.separator = '\t',
-		.delimiter = '\n'
+		.delimiter = '\n',
+		.separator = '\t'
 	}
 };
 
diff --git a/lib/hooks/stats.cpp b/lib/hooks/stats.cpp
index e422f3bd4..879dc52f8 100644
--- a/lib/hooks/stats.cpp
+++ b/lib/hooks/stats.cpp
@@ -225,7 +225,7 @@ public:
 	{
 		assert(state == STATE_STARTED);
 
-		stats_print_periodic(&stats, uri ? output->file : stdout, format, verbose, node);
+		stats_print_periodic(&stats, uri ? output->file : stdout, format, node);
 	}
 
 	virtual void parse(json_t *cfg)
diff --git a/lib/io.c b/lib/io.cpp
similarity index 95%
rename from lib/io.c
rename to lib/io.cpp
index 3beb6f114..b213b3df5 100644
--- a/lib/io.c
+++ b/lib/io.cpp
@@ -33,7 +33,8 @@
 
 static int io_print_lines(struct io *io, struct sample *smps[], unsigned cnt)
 {
-	int ret, i;
+	int ret;
+	unsigned i;
 
 	FILE *f = io_stream_output(io);
 
@@ -52,7 +53,8 @@ static int io_print_lines(struct io *io, struct sample *smps[], unsigned cnt)
 
 static int io_scan_lines(struct io *io, struct sample *smps[], unsigned cnt)
 {
-	int ret, i;
+	int ret;
+	unsigned i;
 
 	FILE *f = io_stream_input(io);
 
@@ -95,8 +97,8 @@ int io_init(struct io *io, const struct format_type *fmt, struct vlist *signals,
 	io->in.buflen =
 	io->out.buflen = 4096;
 
-	io->in.buffer = alloc(io->in.buflen);
-	io->out.buffer = alloc(io->out.buflen);
+	io->in.buffer = (char *) alloc(io->in.buflen);
+	io->out.buffer = (char *) alloc(io->out.buflen);
 
 	io->signals = signals;
 
@@ -114,7 +116,7 @@ int io_init2(struct io *io, const struct format_type *fmt, const char *dt, int f
 	int ret;
 	struct vlist *signals;
 
-	signals = alloc(sizeof(struct vlist));
+	signals = (struct vlist *) alloc(sizeof(struct vlist));
 	signals->state = STATE_DESTROYED;
 
 	ret = vlist_init(signals);
@@ -176,22 +178,22 @@ int io_stream_open(struct io *io, const char *uri)
 			io->mode = IO_MODE_STDIO;
 
 			io->out.stream.std = fopen(uri, "a+");
-			if (io->out.stream.std == NULL)
+			if (io->out.stream.std == nullptr)
 				return -1;
 
 			io->in.stream.std  = fopen(uri, "r");
-			if (io->in.stream.std == NULL)
+			if (io->in.stream.std == nullptr)
 				return -1;
 		}
 		else {
 			io->mode = IO_MODE_ADVIO;
 
 			io->out.stream.adv = afopen(uri, "a+");
-			if (io->out.stream.adv == NULL)
+			if (io->out.stream.adv == nullptr)
 				return -1;
 
 			io->in.stream.adv = afopen(uri, "a+");
-			if (io->in.stream.adv == NULL)
+			if (io->in.stream.adv == nullptr)
 				return -2;
 		}
 	}
@@ -224,11 +226,11 @@ stdio:		io->mode = IO_MODE_STDIO;
 
 	/* Enable line buffering on stdio */
 	if (io->mode == IO_MODE_STDIO) {
-		ret = setvbuf(io->in.stream.std, NULL, _IOLBF, BUFSIZ);
+		ret = setvbuf(io->in.stream.std, nullptr, _IOLBF, BUFSIZ);
 		if (ret)
 			return -1;
 
-		ret = setvbuf(io->out.stream.std, NULL, _IOLBF, BUFSIZ);
+		ret = setvbuf(io->out.stream.std, nullptr, _IOLBF, BUFSIZ);
 		if (ret)
 			return -1;
 	}
diff --git a/lib/kernel/if.c b/lib/kernel/if.cpp
similarity index 97%
rename from lib/kernel/if.c
rename to lib/kernel/if.cpp
index f6c850364..c9a17398f 100644
--- a/lib/kernel/if.c
+++ b/lib/kernel/if.cpp
@@ -58,7 +58,7 @@ int if_init(struct interface *i, struct rtnl_link *link)
 int if_destroy(struct interface *i)
 {
 	/* List members are freed by the nodes they belong to. */
-	vlist_destroy(&i->nodes, NULL, false);
+	vlist_destroy(&i->nodes, nullptr, false);
 
 	rtnl_qdisc_put(i->tc_qdisc);
 
@@ -145,7 +145,7 @@ struct interface * if_get_egress(struct sockaddr *sa, struct vlist *interfaces)
 		error("Failed to get interface for socket address '%s'", buf);
 		free(buf);
 
-		return NULL;
+		return nullptr;
 	}
 
 	/* Search of existing interface with correct ifindex */
@@ -158,13 +158,13 @@ struct interface * if_get_egress(struct sockaddr *sa, struct vlist *interfaces)
 	}
 
 	/* If not found, create a new interface */
-	i = alloc(sizeof(struct interface));
+	i = (struct interface *) alloc(sizeof(struct interface));
 	if (!i)
-		return NULL;
+		return nullptr;
 
 	ret = if_init(i, link);
 	if (ret)
-		NULL;
+		return nullptr;
 
 	vlist_push(interfaces, i);
 
diff --git a/lib/kernel/nl.c b/lib/kernel/nl.cpp
similarity index 93%
rename from lib/kernel/nl.c
rename to lib/kernel/nl.cpp
index f1e769ab5..9f05d35ee 100644
--- a/lib/kernel/nl.c
+++ b/lib/kernel/nl.cpp
@@ -31,7 +31,7 @@
 #include <villas/kernel/nl.h>
 
 /** Singleton for global netlink socket */
-static struct nl_sock *sock = NULL;
+static struct nl_sock *sock = nullptr;
 
 struct nl_sock * nl_init()
 {
@@ -64,7 +64,7 @@ void nl_shutdown()
 	nl_close(sock);
 	nl_socket_free(sock);
 
-	sock = NULL;
+	sock = nullptr;
 }
 
 static int egress_cb(struct nl_msg *msg, void *arg)
@@ -83,12 +83,12 @@ int nl_get_egress(struct nl_addr *addr)
 	struct nl_sock *sock = nl_init();
 	struct nl_cb *cb;
 	struct nl_msg *msg = nlmsg_alloc_simple(RTM_GETROUTE, 0);
-	struct rtnl_route *route = NULL;
+	struct rtnl_route *route = nullptr;
 
 	/* Build message */
 	struct rtmsg rmsg = {
-		.rtm_family = nl_addr_get_family(addr),
-		.rtm_dst_len = nl_addr_get_prefixlen(addr),
+		.rtm_family = (unsigned char) nl_addr_get_family(addr),
+		.rtm_dst_len = (unsigned char) nl_addr_get_prefixlen(addr),
 	};
 
 	ret = nlmsg_append(msg, &rmsg, sizeof(rmsg), NLMSG_ALIGNTO);
diff --git a/lib/kernel/tc.c b/lib/kernel/tc.cpp
similarity index 98%
rename from lib/kernel/tc.c
rename to lib/kernel/tc.cpp
index 0db8beaf5..904187072 100644
--- a/lib/kernel/tc.c
+++ b/lib/kernel/tc.cpp
@@ -47,7 +47,7 @@ int tc_prio(struct interface *i, struct rtnl_qdisc **qd, tc_hdl_t handle, tc_hdl
 	/* This is the default priomap used by the tc-prio qdisc
 	 * We will use the first 'bands' bands internally */
 	uint8_t map[] = QDISC_PRIO_DEFAULT_PRIOMAP;
-	for (int i = 0; i < ARRAY_LEN(map); i++)
+	for (unsigned i = 0; i < ARRAY_LEN(map); i++)
 		map[i] += bands;
 
 	rtnl_tc_set_link(TC_CAST(q), i->nl_link);
diff --git a/lib/kernel/tc_netem.c b/lib/kernel/tc_netem.cpp
similarity index 95%
rename from lib/kernel/tc_netem.c
rename to lib/kernel/tc_netem.cpp
index b29834fcb..1349e9f0f 100644
--- a/lib/kernel/tc_netem.c
+++ b/lib/kernel/tc_netem.cpp
@@ -40,14 +40,14 @@ int tc_netem_parse(struct rtnl_qdisc **netem, json_t *cfg)
 {
 	int ret, val;
 
-	json_t *json_limit = NULL;
-	json_t *json_delay = NULL;
-	json_t *json_delay_distribution = NULL;
-	json_t *json_delay_correlation = NULL;
-	json_t *json_jitter = NULL;
-	json_t *json_loss = NULL;
-	json_t *json_duplicate = NULL;
-	json_t *json_corruption = NULL;
+	json_t *json_limit = nullptr;
+	json_t *json_delay = nullptr;
+	json_t *json_delay_distribution = nullptr;
+	json_t *json_delay_correlation = nullptr;
+	json_t *json_jitter = nullptr;
+	json_t *json_loss = nullptr;
+	json_t *json_duplicate = nullptr;
+	json_t *json_corruption = nullptr;
 
 	json_error_t err;
 
@@ -161,7 +161,7 @@ int tc_netem_parse(struct rtnl_qdisc **netem, json_t *cfg)
 
 char * tc_netem_print(struct rtnl_qdisc *ne)
 {
-	char *buf = NULL;
+	char *buf = nullptr;
 
 	if (rtnl_netem_get_limit(ne) > 0)
 		strcatf(&buf, "limit %upkts", rtnl_netem_get_limit(ne));
@@ -241,7 +241,7 @@ int rtnl_netem_set_delay_distribution_data(struct rtnl_qdisc *qdisc, short *data
 {
 	struct rtnl_netem *netem;
 
-	if (!(netem = rtnl_tc_data(TC_CAST(qdisc))))
+	if (!(netem = (struct rtnl_netem *) rtnl_tc_data(TC_CAST(qdisc))))
 		return -1;
 
 	if (len > MAXDIST)
diff --git a/lib/mapping.c b/lib/mapping.cpp
similarity index 88%
rename from lib/mapping.c
rename to lib/mapping.cpp
index 5698ea447..ada858d13 100644
--- a/lib/mapping.c
+++ b/lib/mapping.cpp
@@ -44,18 +44,18 @@ int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *n
 			goto invalid_format;
 		}
 
-		me->node = vlist_lookup(nodes, node);
+		me->node = (struct node *) vlist_lookup(nodes, node);
 		if (!me->node) {
 			warning("Unknown node %s", node);
 			goto invalid_format;
 		}
 
-		type = strtok_r(NULL, ".[", &lasts);
+		type = strtok_r(nullptr, ".[", &lasts);
 		if (!type)
-			type = "data";
+			type = strf("data");
 	}
 	else {
-		me->node = NULL;
+		me->node = nullptr;
 
 		type = strtok_r(cpy, ".[", &lasts);
 		if (!type)
@@ -66,11 +66,11 @@ int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *n
 		me->type = MAPPING_TYPE_STATS;
 		me->length = 1;
 
-		char *metric = strtok_r(NULL, ".", &lasts);
+		char *metric = strtok_r(nullptr, ".", &lasts);
 		if (!metric)
 			goto invalid_format;
 
-		type = strtok_r(NULL, ".", &lasts);
+		type = strtok_r(nullptr, ".", &lasts);
 		if (!type)
 			goto invalid_format;
 
@@ -86,7 +86,7 @@ int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *n
 		me->type = MAPPING_TYPE_HEADER;
 		me->length = 1;
 
-		field = strtok_r(NULL, ".", &lasts);
+		field = strtok_r(nullptr, ".", &lasts);
 		if (!field) {
 			warning("Missing header type");
 			goto invalid_format;
@@ -105,7 +105,7 @@ int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *n
 		me->type = MAPPING_TYPE_TIMESTAMP;
 		me->length = 2;
 
-		field = strtok_r(NULL, ".", &lasts);
+		field = strtok_r(nullptr, ".", &lasts);
 		if (!field) {
 			warning("Missing timestamp type");
 			goto invalid_format;
@@ -126,7 +126,7 @@ int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *n
 
 		me->type = MAPPING_TYPE_DATA;
 
-		first_str = strtok_r(NULL, "-]", &lasts);
+		first_str = strtok_r(nullptr, "-]", &lasts);
 		if (first_str) {
 			if (me->node)
 				first = vlist_lookup_index(&me->node->in.signals, first_str);
@@ -147,7 +147,7 @@ int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *n
 			goto end;
 		}
 
-		last_str = strtok_r(NULL, "]", &lasts);
+		last_str = strtok_r(nullptr, "]", &lasts);
 		if (last_str) {
 			if (me->node)
 				last = vlist_lookup_index(&me->node->in.signals, last_str);
@@ -174,7 +174,7 @@ int mapping_parse_str(struct mapping_entry *me, const char *str, struct vlist *n
 		goto invalid_format;
 
 end:	/* Check that there is no garbage at the end */
-	end = strtok_r(NULL, "", &lasts);
+	end = strtok_r(nullptr, "", &lasts);
 	if (end)
 		goto invalid_format;
 
@@ -236,14 +236,15 @@ out:	json_decref(json_mapping);
 
 int mapping_update(const struct mapping_entry *me, struct sample *remapped, const struct sample *original)
 {
-	if (me->length + me->offset > remapped->capacity)
+	unsigned len = me->length;
+
+	if (me->offset + len > remapped->capacity)
 		return -1;
 
 	switch (me->type) {
-		case MAPPING_TYPE_STATS: {
+		case MAPPING_TYPE_STATS:
 			remapped->data[me->offset] = stats_get_value(me->node->stats, me->stats.metric, me->stats.type);
 			break;
-		}
 
 		case MAPPING_TYPE_TIMESTAMP: {
 			const struct timespec *ts;
@@ -261,7 +262,6 @@ int mapping_update(const struct mapping_entry *me, struct sample *remapped, cons
 
 			remapped->data[me->offset + 0].i = ts->tv_sec;
 			remapped->data[me->offset + 1].i = ts->tv_nsec;
-
 			break;
 		}
 
@@ -278,20 +278,28 @@ int mapping_update(const struct mapping_entry *me, struct sample *remapped, cons
 				default:
 					return -1;
 			}
-
 			break;
 
 		case MAPPING_TYPE_DATA:
-			for (int j = me->data.offset, i = me->offset; j < me->length + me->data.offset; j++, i++) {
+			for (unsigned j = me->data.offset,
+				 i = me->offset;
+			         j < MIN(original->length, (unsigned) (me->data.offset + me->length));
+				 j++,
+				 i++)
+			{
 				if (j >= original->length)
 					remapped->data[i].f = -1;
 				else
 					remapped->data[i] = original->data[j];
 			}
 
+			len = MIN((unsigned) me->length, original->length - me->data.offset);
 			break;
 	}
 
+	if (me->offset + len > remapped->length)
+		remapped->length = me->offset + len;
+
 	return 0;
 }
 
@@ -332,7 +340,7 @@ int mapping_to_str(const struct mapping_entry *me, unsigned index, char **str)
 {
 	const char *type;
 
-	assert(me->length == 0 || index < me->length);
+	assert(me->length == 0 || (int) index < me->length);
 
 	if (me->node)
 		strcatf(str, "%s.", node_name_short(me->node));
@@ -356,7 +364,7 @@ int mapping_to_str(const struct mapping_entry *me, unsigned index, char **str)
 					break;
 
 				default:
-					type = NULL;
+					type = nullptr;
 			}
 
 			strcatf(str, "hdr.%s", type);
@@ -373,7 +381,7 @@ int mapping_to_str(const struct mapping_entry *me, unsigned index, char **str)
 					break;
 
 				default:
-					type = NULL;
+					type = nullptr;
 			}
 
 			strcatf(str, "ts.%s.%s", type, index == 0 ? "sec" : "nsec");
@@ -381,7 +389,7 @@ int mapping_to_str(const struct mapping_entry *me, unsigned index, char **str)
 
 		case MAPPING_TYPE_DATA:
 			if (me->node && index < vlist_length(&me->node->in.signals)) {
-				struct signal *s = vlist_at(&me->node->in.signals, index);
+				struct signal *s = (struct signal *) vlist_at(&me->node->in.signals, index);
 
 				strcatf(str, "data[%s]", s->name);
 			}
diff --git a/lib/memory.c b/lib/memory.cpp
similarity index 97%
rename from lib/memory.c
rename to lib/memory.cpp
index a2f0b58d6..a227619ce 100644
--- a/lib/memory.c
+++ b/lib/memory.cpp
@@ -47,7 +47,7 @@ __attribute__((destructor))
 static void destroy_allocations()
 {
 	/** @todo: Release remaining allocations? */
-	hash_table_destroy(&allocations, NULL, false);
+	hash_table_destroy(&allocations, nullptr, false);
 }
 
 int memory_init(int hugepages)
@@ -127,15 +127,15 @@ void * memory_alloc_aligned(struct memory_type *m, size_t len, size_t alignment)
 	int ret;
 
 	struct memory_allocation *ma = m->alloc(m, len, alignment);
-	if (ma == NULL) {
+	if (ma == nullptr) {
 		warning("Memory allocation of type %s failed. reason=%s", m->name, strerror(errno) );
-		return NULL;
+		return nullptr;
 	}
 
 	ret = hash_table_insert(&allocations, ma->address, ma);
 	if (ret) {
 		warning("Inserting into hash table failed!");
-		return NULL;
+		return nullptr;
 	}
 
 	debug(LOG_MEM | 5, "Allocated %#zx bytes of %#zx-byte-aligned %s memory: %p", ma->length, ma->alignment, ma->type->name, ma->address);
@@ -181,5 +181,5 @@ struct memory_type * memory_type_lookup(enum memory_type_flags flags)
 	else if (flags & MEMORY_HEAP)
 		return &memory_heap;
 	else
-		return NULL;
+		return nullptr;
 }
diff --git a/lib/memory/heap.c b/lib/memory/heap.cpp
similarity index 90%
rename from lib/memory/heap.c
rename to lib/memory/heap.cpp
index 5efaad642..1f8f001ef 100644
--- a/lib/memory/heap.c
+++ b/lib/memory/heap.cpp
@@ -29,9 +29,9 @@ static struct memory_allocation * memory_heap_alloc(struct memory_type *m, size_
 {
 	int ret;
 
-	struct memory_allocation *ma = alloc(sizeof(struct memory_allocation));
+	struct memory_allocation *ma = (struct memory_allocation *) alloc(sizeof(struct memory_allocation));
 	if (!ma)
-		return NULL;
+		return nullptr;
 
 	ma->alignment = alignment;
 	ma->type = m;
@@ -43,7 +43,7 @@ static struct memory_allocation * memory_heap_alloc(struct memory_type *m, size_
 	ret = posix_memalign(&ma->address, ma->alignment, ma->length);
 	if (ret) {
 		free(ma);
-		return NULL;
+		return nullptr;
 	}
 
 	return ma;
@@ -60,7 +60,7 @@ static int memory_heap_free(struct memory_type *m, struct memory_allocation *ma)
 struct memory_type memory_heap = {
 	.name = "heap",
 	.flags = MEMORY_HEAP,
+	.alignment = 1,
 	.alloc = memory_heap_alloc,
-	.free = memory_heap_free,
-	.alignment = 1
+	.free = memory_heap_free
 };
diff --git a/lib/memory/hugepage.c b/lib/memory/hugepage.cpp
similarity index 92%
rename from lib/memory/hugepage.c
rename to lib/memory/hugepage.cpp
index 0cb58c3f7..935060dab 100644
--- a/lib/memory/hugepage.c
+++ b/lib/memory/hugepage.cpp
@@ -82,9 +82,9 @@ static struct memory_allocation * memory_hugepage_alloc(struct memory_type *m, s
 	int flags, fd;
 	size_t sz;
 
-	struct memory_allocation *ma = alloc(sizeof(struct memory_allocation));
+	struct memory_allocation *ma = (struct memory_allocation *) alloc(sizeof(struct memory_allocation));
 	if (!ma)
-		return NULL;
+		return nullptr;
 
 retry:	if (use_huge) {
 #ifdef __linux__
@@ -115,7 +115,7 @@ retry:	if (use_huge) {
 	ma->alignment = ALIGN(alignment, sz);
 	ma->type = m;
 
-	ma->address = mmap(NULL, ma->length, PROT_READ | PROT_WRITE, flags, fd, 0);
+	ma->address = mmap(nullptr, ma->length, PROT_READ | PROT_WRITE, flags, fd, 0);
 	if (ma->address == MAP_FAILED) {
 		if (use_huge) {
 			warning("Failed to map hugepages, try with normal pages instead!");
@@ -124,7 +124,7 @@ retry:	if (use_huge) {
 		}
 		else {
 			free(ma);
-			return NULL;
+			return nullptr;
 		}
 	}
 
@@ -145,7 +145,7 @@ static int memory_hugepage_free(struct memory_type *m, struct memory_allocation
 struct memory_type memory_hugepage = {
 	.name = "mmap_hugepages",
 	.flags = MEMORY_MMAP | MEMORY_HUGEPAGE,
+	.alignment = 21, /* 2 MiB hugepage */
 	.alloc = memory_hugepage_alloc,
-	.free = memory_hugepage_free,
-	.alignment = 21 /* 2 MiB hugepage */
+	.free = memory_hugepage_free
 };
diff --git a/lib/memory/ib.c b/lib/memory/ib.cpp
similarity index 91%
rename from lib/memory/ib.c
rename to lib/memory/ib.cpp
index e1fd9d411..9a85368e8 100644
--- a/lib/memory/ib.c
+++ b/lib/memory/ib.cpp
@@ -42,9 +42,9 @@ static struct memory_allocation * memory_ib_alloc(struct memory_type *m, size_t
 {
 	struct memory_ib *mi = (struct memory_ib *) m->_vd;
 
-	struct memory_allocation *ma = alloc(sizeof(struct memory_allocation));
+	struct memory_allocation *ma = (struct memory_allocation *) alloc(sizeof(struct memory_allocation));
 	if (!ma)
-		return NULL;
+		return nullptr;
 
 	ma->type = m;
 	ma->length = len;
@@ -60,7 +60,7 @@ static struct memory_allocation * memory_ib_alloc(struct memory_type *m, size_t
 	if (!ma->ib.mr) {
 		mi->parent->free(mi->parent, ma->parent);
 		free(ma);
-		return NULL;
+		return nullptr;
 	}
 
 	return ma;
@@ -83,7 +83,7 @@ static int memory_ib_free(struct memory_type *m, struct memory_allocation *ma)
 struct memory_type * memory_ib(struct node *n, struct memory_type *parent)
 {
 	struct infiniband *i = (struct infiniband *) n->_vd;
-	struct memory_type *mt = malloc(sizeof(struct memory_type));
+	struct memory_type *mt = (struct memory_type *) malloc(sizeof(struct memory_type));
 
 	mt->name = "ib";
 	mt->flags = 0;
diff --git a/lib/memory/managed.c b/lib/memory/managed.cpp
similarity index 94%
rename from lib/memory/managed.c
rename to lib/memory/managed.cpp
index d5024ea84..27b2d6ae4 100644
--- a/lib/memory/managed.c
+++ b/lib/memory/managed.cpp
@@ -40,7 +40,7 @@ static struct memory_allocation * memory_managed_alloc(struct memory_type *m, si
 	struct memory_block *first = (struct memory_block *) m->_vd;
 	struct memory_block *block;
 
-	for (block = first; block != NULL; block = block->next) {
+	for (block = first; block != nullptr; block = block->next) {
 		if (block->used)
 			continue;
 
@@ -104,9 +104,9 @@ static struct memory_allocation * memory_managed_alloc(struct memory_type *m, si
 
 			block->used = true;
 
-			struct memory_allocation *ma = alloc(sizeof(struct memory_allocation));
+			struct memory_allocation *ma = (struct memory_allocation *) alloc(sizeof(struct memory_allocation));
 			if (!ma)
-				return NULL;
+				return nullptr;
 
 			ma->address = cptr;
 			ma->type = m;
@@ -119,7 +119,7 @@ static struct memory_allocation * memory_managed_alloc(struct memory_type *m, si
 	}
 
 	/* No suitable block found */
-	return NULL;
+	return nullptr;
 }
 
 static int memory_managed_free(struct memory_type *m, struct memory_allocation *ma)
@@ -157,13 +157,13 @@ static int memory_managed_free(struct memory_type *m, struct memory_allocation *
 
 struct memory_type * memory_managed(void *ptr, size_t len)
 {
-	struct memory_type *mt = ptr;
+	struct memory_type *mt = (struct memory_type *) ptr;
 	struct memory_block *mb;
-	char *cptr = ptr;
+	char *cptr = (char *) ptr;
 
 	if (len < sizeof(struct memory_type) + sizeof(struct memory_block)) {
 		info("memory_managed: passed region too small");
-		return NULL;
+		return nullptr;
 	}
 
 	/* Initialize memory_type */
@@ -177,8 +177,8 @@ struct memory_type * memory_managed(void *ptr, size_t len)
 
 	/* Initialize first free memory block */
 	mb = (struct memory_block *) cptr;
-	mb->prev = NULL;
-	mb->next = NULL;
+	mb->prev = nullptr;
+	mb->next = nullptr;
 	mb->used = false;
 
 	cptr += ALIGN(sizeof(struct memory_block), sizeof(void *));
diff --git a/lib/node.c b/lib/node.cpp
similarity index 98%
rename from lib/node.c
rename to lib/node.cpp
index b2a22515d..5bcd28463 100644
--- a/lib/node.c
+++ b/lib/node.cpp
@@ -167,7 +167,7 @@ int node_parse(struct node *n, json_t *json, const char *name)
 
 	const char *fields[] = { "signals", "builtin", "vectorize", "hooks" };
 
-	for (int j = 0; j < ARRAY_LEN(dirs); j++) {
+	for (unsigned j = 0; j < ARRAY_LEN(dirs); j++) {
 		json_t *json_dir = json_object_get(json, dirs[j].str);
 
 		/* Skip if direction is unused */
@@ -175,7 +175,7 @@ int node_parse(struct node *n, json_t *json, const char *name)
 			json_dir = json_pack("{ s: b }", "enabled", 0);
 
 		/* Copy missing fields from main node config to direction config */
-		for (int i = 0; i < ARRAY_LEN(fields); i++) {
+		for (unsigned i = 0; i < ARRAY_LEN(fields); i++) {
 			json_t *json_field_dir  = json_object_get(json_dir, fields[i]);
 			json_t *json_field_node = json_object_get(json, fields[i]);
 
@@ -555,7 +555,7 @@ int node_list_parse(struct vlist *list, json_t *cfg, struct vlist *all)
 	switch (json_typeof(cfg)) {
 		case JSON_STRING:
 			str = json_string_value(cfg);
-			node = vlist_lookup(all, str);
+			node = (struct node *) vlist_lookup(all, str);
 			if (!node)
 				goto invalid2;
 
@@ -567,7 +567,7 @@ int node_list_parse(struct vlist *list, json_t *cfg, struct vlist *all)
 				if (!json_is_string(elm))
 					goto invalid;
 
-				node = vlist_lookup(all, json_string_value(elm));
+				node = (struct node *) vlist_lookup(all, json_string_value(elm));
 				if (!node)
 					goto invalid;
 
diff --git a/lib/node_direction.c b/lib/node_direction.cpp
similarity index 98%
rename from lib/node_direction.c
rename to lib/node_direction.cpp
index 401bdd406..6aac8122a 100644
--- a/lib/node_direction.c
+++ b/lib/node_direction.cpp
@@ -146,8 +146,8 @@ int node_direction_parse(struct node_direction *nd, struct node *n, json_t *cfg)
 			);
 		}
 
-		int type = signal_type_from_str(type_str);
-		if (type < 0)
+		enum signal_type type = signal_type_from_str(type_str);
+		if (type == SIGNAL_TYPE_INVALID)
 			error("Invalid signal type %s", type_str);
 
 		ret = signal_list_generate(&nd->signals, count, type);
diff --git a/lib/node_type.c b/lib/node_type.cpp
similarity index 100%
rename from lib/node_type.c
rename to lib/node_type.cpp
diff --git a/lib/nodes/CMakeLists.txt b/lib/nodes/CMakeLists.txt
index 5fe860a46..6a8e82a75 100644
--- a/lib/nodes/CMakeLists.txt
+++ b/lib/nodes/CMakeLists.txt
@@ -32,7 +32,7 @@ if(WITH_NODE_INFLUXDB)
 endif()
 
 if(WITH_NODE_STATS)
-    list(APPEND NODE_SRC stats.c)
+    list(APPEND NODE_SRC stats.cpp)
 endif()
 
 if(WITH_NODE_SIGNAL)
diff --git a/lib/nodes/rtp.cpp b/lib/nodes/rtp.cpp
index f99865618..8a5054bdd 100644
--- a/lib/nodes/rtp.cpp
+++ b/lib/nodes/rtp.cpp
@@ -55,10 +55,8 @@ static pthread_t re_pthread;
 
 using namespace villas::node;
 
-extern "C" {
-
 /* Forward declarations */
-extern struct plugin p;
+static struct plugin p;
 
 static int rtp_set_rate(struct node *n, double rate)
 {
@@ -646,8 +644,6 @@ int rtp_netem_fds(struct node *n, int fds[])
 	return m;
 }
 
-struct plugin p;
-
 __attribute__((constructor(110)))
 static void register_plugin() {
 	p.name		= "rtp";
@@ -682,5 +678,3 @@ static void deregister_plugin() {
 	if (plugins.state != STATE_DESTROYED)
 		vlist_remove_all(&plugins, &p);
 }
-
-} /* extern C */
diff --git a/lib/nodes/stats.c b/lib/nodes/stats.cpp
similarity index 83%
rename from lib/nodes/stats.c
rename to lib/nodes/stats.cpp
index 51224d647..4226e9694 100644
--- a/lib/nodes/stats.c
+++ b/lib/nodes/stats.cpp
@@ -26,7 +26,7 @@
 
 #include <string.h>
 
-#include <villas/nodes/stats.h>
+#include <villas/nodes/stats.hpp>
 #include <villas/hook.h>
 #include <villas/plugin.h>
 #include <villas/stats.h>
@@ -65,11 +65,11 @@ int stats_node_signal_parse(struct stats_node_signal *s, json_t *cfg)
 	if (!node)
 		goto invalid_format;
 
-	metric = strtok_r(NULL, ".", &lasts);
+	metric = strtok_r(nullptr, ".", &lasts);
 	if (!metric)
 		goto invalid_format;
 
-	type = strtok_r(NULL, ".", &lasts);
+	type = strtok_r(nullptr, ".", &lasts);
 	if (!type)
 		goto invalid_format;
 
@@ -110,7 +110,7 @@ int stats_node_start(struct node *n)
 	for (size_t i = 0; i < vlist_length(&s->signals); i++) {
 		struct stats_node_signal *stats_sig = (struct stats_node_signal *) vlist_at(&s->signals, i);
 
-		stats_sig->node = vlist_lookup(nodes, stats_sig->node_str);
+		stats_sig->node = (struct node *) vlist_lookup(nodes, stats_sig->node_str);
 		if (!stats_sig->node)
 			error("Invalid reference node %s for setting 'node' of node %s", stats_sig->node_str, node_name(n));
 	}
@@ -188,7 +188,7 @@ int stats_node_parse(struct node *n, json_t *cfg)
 		struct signal *sig = (struct signal *) vlist_at(&n->in.signals, i);
 		struct stats_node_signal *stats_sig;
 
-		stats_sig = alloc(sizeof(struct stats_node_signal));
+		stats_sig = (struct stats_node_signal *) alloc(sizeof(struct stats_node_signal));
 		if (!stats_sig)
 			return -1;
 
@@ -224,7 +224,7 @@ int stats_node_read(struct node *n, struct sample *smps[], unsigned cnt, unsigne
 
 	task_wait(&s->task);
 
-	int len = MIN(vlist_length(&s->signals), smps[0]->capacity);
+	unsigned len = MIN(vlist_length(&s->signals), smps[0]->capacity);
 
 	for (size_t i = 0; i < len; i++) {
 		struct stats *st;
@@ -253,27 +253,33 @@ int stats_node_poll_fds(struct node *n, int fds[])
 	return 0;
 }
 
-static struct plugin p = {
-	.name		= "stats",
-	.description	= "Send statistics to another node",
-	.type		= PLUGIN_TYPE_NODE,
-	.node		= {
-		.vectorize	= 1,
-		.flags		= 0,
-		.size		= sizeof(struct stats_node),
-		.type.start	= stats_node_type_start,
-		.parse		= stats_node_parse,
-		.init		= stats_node_init,
-		.destroy	= stats_node_destroy,
-		.print		= stats_node_print,
-		.start		= stats_node_start,
-		.stop		= stats_node_stop,
-		.read		= stats_node_read,
-		.poll_fds	= stats_node_poll_fds,
-	}
-};
+static struct plugin p;
 
-REGISTER_PLUGIN(&p)
-LIST_INIT_STATIC(&p.node.instances)
+__attribute__((constructor(110)))
+static void register_plugin() {
+	p.name		= "stats";
+	p.description	= "Send statistics to another node";
+	p.type		= PLUGIN_TYPE_NODE;
+	p.node.vectorize	= 1;
+	p.node.flags		= 0;
+	p.node.size		= sizeof(struct stats_node);
+	p.node.type.start	= stats_node_type_start;
+	p.node.parse		= stats_node_parse;
+	p.node.init		= stats_node_init;
+	p.node.destroy	= stats_node_destroy;
+	p.node.print		= stats_node_print;
+	p.node.start		= stats_node_start;
+	p.node.stop		= stats_node_stop;
+	p.node.read		= stats_node_read;
+	p.node.poll_fds	= stats_node_poll_fds;
+
+	vlist_push(&plugins, &p);
+}
+
+__attribute__((destructor(110)))
+static void deregister_plugin() {
+	if (plugins.state != STATE_DESTROYED)
+		vlist_remove_all(&plugins, &p);
+}
 
 /** @} */
diff --git a/lib/path.c b/lib/path.cpp
similarity index 95%
rename from lib/path.c
rename to lib/path.cpp
index ade198087..5373db3f8 100644
--- a/lib/path.c
+++ b/lib/path.cpp
@@ -46,7 +46,7 @@
 static void * path_run_single(void *arg)
 {
 	int ret;
-	struct path *p = arg;
+	struct path *p = (struct path *) arg;
 	struct path_source *ps = (struct path_source *) vlist_at(&p->sources, 0);
 
 	while (p->state == STATE_STARTED) {
@@ -70,7 +70,7 @@ static void * path_run_single(void *arg)
 static void * path_run_poll(void *arg)
 {
 	int ret;
-	struct path *p = arg;
+	struct path *p = (struct path *) arg;
 
 	while (p->state == STATE_STARTED) {
 		ret = poll(p->reader.pfds, p->reader.nfds, -1);
@@ -156,7 +156,7 @@ static int path_prepare_poll(struct path *p)
 	p->reader.pfds = NULL;
 	p->reader.nfds = 0;
 
-	for (int i = 0; i < vlist_length(&p->sources); i++) {
+	for (unsigned i = 0; i < vlist_length(&p->sources); i++) {
 		struct path_source *ps = (struct path_source *) vlist_at(&p->sources, i);
 
 		m = node_poll_fds(ps->node, fds);
@@ -164,7 +164,7 @@ static int path_prepare_poll(struct path *p)
 			continue;
 
 		p->reader.nfds += m;
-		p->reader.pfds = realloc(p->reader.pfds, p->reader.nfds * sizeof(struct pollfd));
+		p->reader.pfds = (struct pollfd *) realloc(p->reader.pfds, p->reader.nfds * sizeof(struct pollfd));
 
 		for (int i = 0; i < m; i++) {
 			if (fds[i] < 0)
@@ -183,7 +183,7 @@ static int path_prepare_poll(struct path *p)
 			return ret;
 
 		p->reader.nfds++;
-		p->reader.pfds = realloc(p->reader.pfds, p->reader.nfds * sizeof(struct pollfd));
+		p->reader.pfds = (struct pollfd *) realloc(p->reader.pfds, p->reader.nfds * sizeof(struct pollfd));
 
 		p->reader.pfds[p->reader.nfds-1].events = POLLIN;
 		p->reader.pfds[p->reader.nfds-1].fd = task_fd(&p->timeout);
@@ -202,7 +202,7 @@ int path_prepare(struct path *p)
 
 	/* Initialize destinations */
 	struct memory_type *pool_mt = &memory_hugepage;
-	int pool_size = MAX(1, vlist_length(&p->destinations)) * p->queuelen;
+	unsigned pool_size = MAX(1UL, vlist_length(&p->destinations)) * p->queuelen;
 
 	for (size_t i = 0; i < vlist_length(&p->destinations); i++) {
 		struct path_destination *pd = (struct path_destination *) vlist_at(&p->destinations, i);
@@ -240,7 +240,7 @@ int path_prepare(struct path *p)
 			struct mapping_entry *me = (struct mapping_entry *) vlist_at(&ps->mappings, i);
 			struct vlist *sigs = node_get_signals(me->node, NODE_DIR_IN);
 
-			for (int j = 0; j < me->length; j++) {
+			for (unsigned j = 0; j < (unsigned) me->length; j++) {
 				struct signal *sig;
 
 				/* For data mappings we simple refer to the existing
@@ -256,7 +256,7 @@ int path_prepare(struct path *p)
 				}
 				/* For other mappings we create new signal descriptors */
 				else {
-					sig = alloc(sizeof(struct signal));
+					sig = (struct signal *) alloc(sizeof(struct signal));
 
 					ret = signal_init_from_mapping(sig, me, j);
 					if (ret)
@@ -371,7 +371,7 @@ int path_parse(struct path *p, json_t *cfg, struct vlist *nodes)
 
 		/* Create new path_source of not existing */
 		if (!ps) {
-			ps = alloc(sizeof(struct path_source));
+			ps = (struct path_source *) alloc(sizeof(struct path_source));
 
 			ps->node = me->node;
 			ps->masked = false;
@@ -418,7 +418,7 @@ int path_parse(struct path *p, json_t *cfg, struct vlist *nodes)
 			if (!name)
 				error("The 'mask' setting must be a list of node names");
 
-			node = vlist_lookup(nodes, name);
+			node = (struct node *) vlist_lookup(nodes, name);
 			if (!node)
 				error("The 'mask' entry '%s' is not a valid node name", name);
 
@@ -534,14 +534,23 @@ int path_check(struct path *p)
 int path_start(struct path *p)
 {
 	int ret;
-	char *mode, *mask;
+	const char *mode;
+	char *mask;
 
 	assert(p->state == STATE_PREPARED);
 
 	switch (p->mode) {
-		case PATH_MODE_ANY: mode = "any";     break;
-		case PATH_MODE_ALL: mode = "all";     break;
-		default:            mode = "unknown"; break;
+		case PATH_MODE_ANY:
+			mode = "any";
+			break;
+
+		case PATH_MODE_ALL:
+			mode = "all";
+			break;
+
+		default:
+			mode = "unknown";
+			break;
 	}
 
 	mask = bitset_dump(&p->mask);
@@ -579,7 +588,7 @@ int path_start(struct path *p)
 	if (!p->last_sample)
 		return -1;
 
-	p->last_sample->length = vlist_length(&p->signals);
+	p->last_sample->length = 0;
 	p->last_sample->signals = &p->signals;
 	p->last_sample->sequence = 0;
 	p->last_sample->flags = p->last_sample->length > 0 ? SAMPLE_HAS_DATA : 0;
diff --git a/lib/path_destination.c b/lib/path_destination.cpp
similarity index 100%
rename from lib/path_destination.c
rename to lib/path_destination.cpp
diff --git a/lib/path_source.c b/lib/path_source.cpp
similarity index 100%
rename from lib/path_source.c
rename to lib/path_source.cpp
diff --git a/lib/plugin.c b/lib/plugin.cpp
similarity index 100%
rename from lib/plugin.c
rename to lib/plugin.cpp
diff --git a/lib/pool.c b/lib/pool.cpp
similarity index 98%
rename from lib/pool.c
rename to lib/pool.cpp
index a77ac3617..00af3ffa5 100644
--- a/lib/pool.c
+++ b/lib/pool.cpp
@@ -48,7 +48,7 @@ int pool_init(struct pool *p, size_t cnt, size_t blocksz, struct memory_type *m)
 	if (ret)
 		return ret;
 
-	for (int i = 0; i < cnt; i++)
+	for (unsigned i = 0; i < cnt; i++)
 		queue_push(&p->queue, (char *) buffer + i * p->blocksz);
 
 	p->state = STATE_INITIALIZED;
diff --git a/lib/queue.c b/lib/queue.cpp
similarity index 73%
rename from lib/queue.c
rename to lib/queue.cpp
index 37a5eb2ab..8f560a009 100644
--- a/lib/queue.c
+++ b/lib/queue.cpp
@@ -55,10 +55,10 @@ int queue_init(struct queue *q, size_t size, struct memory_type *m)
 	q->buffer_off = (char *) buffer - (char *) q;
 
 	for (size_t i = 0; i != size; i += 1)
-		atomic_store_explicit(&buffer[i].sequence, i, memory_order_relaxed);
+		std::atomic_store_explicit(&buffer[i].sequence, i, std::memory_order_relaxed);
 
-	atomic_store_explicit(&q->tail, 0, memory_order_relaxed);
-	atomic_store_explicit(&q->head, 0, memory_order_relaxed);
+	std::atomic_store_explicit(&q->tail, 0ul, std::memory_order_relaxed);
+	std::atomic_store_explicit(&q->head, 0ul, std::memory_order_relaxed);
 
 	q->state = STATE_INITIALIZED;
 
@@ -82,8 +82,8 @@ int queue_destroy(struct queue *q)
 
 size_t queue_available(struct queue *q)
 {
-	return  atomic_load_explicit(&q->tail, memory_order_relaxed) -
-		atomic_load_explicit(&q->head, memory_order_relaxed);
+	return std::atomic_load_explicit(&q->tail, std::memory_order_relaxed) -
+		std::atomic_load_explicit(&q->head, std::memory_order_relaxed);
 }
 
 int queue_push(struct queue *q, void *ptr)
@@ -92,28 +92,28 @@ int queue_push(struct queue *q, void *ptr)
 	size_t pos, seq;
 	intptr_t diff;
 
-	if (atomic_load_explicit(&q->state, memory_order_relaxed) == STATE_STOPPED)
+	if (std::atomic_load_explicit(&q->state, std::memory_order_relaxed) == STATE_STOPPED)
 		return -1;
 
 	buffer = (struct queue_cell *) ((char *) q + q->buffer_off);
-	pos = atomic_load_explicit(&q->tail, memory_order_relaxed);
+	pos = std::atomic_load_explicit(&q->tail, std::memory_order_relaxed);
 	for (;;) {
 		cell = &buffer[pos & q->buffer_mask];
-		seq = atomic_load_explicit(&cell->sequence, memory_order_acquire);
+		seq = std::atomic_load_explicit(&cell->sequence, std::memory_order_acquire);
 		diff = (intptr_t) seq - (intptr_t) pos;
 
 		if (diff == 0) {
-			if (atomic_compare_exchange_weak_explicit(&q->tail, &pos, pos + 1, memory_order_relaxed, memory_order_relaxed))
+			if (std::atomic_compare_exchange_weak_explicit(&q->tail, &pos, pos + 1, std::memory_order_relaxed, std::memory_order_relaxed))
 				break;
 		}
 		else if (diff < 0)
 			return 0;
 		else
-			pos = atomic_load_explicit(&q->tail, memory_order_relaxed);
+			pos = std::atomic_load_explicit(&q->tail, std::memory_order_relaxed);
 	}
 
 	cell->data_off = (char *) ptr - (char *) q;
-	atomic_store_explicit(&cell->sequence, pos + 1, memory_order_release);
+	std::atomic_store_explicit(&cell->sequence, pos + 1, std::memory_order_release);
 
 	return 1;
 }
@@ -124,28 +124,28 @@ int queue_pull(struct queue *q, void **ptr)
 	size_t pos, seq;
 	intptr_t diff;
 
-	if (atomic_load_explicit(&q->state, memory_order_relaxed) == STATE_STOPPED)
+	if (std::atomic_load_explicit(&q->state, std::memory_order_relaxed) == STATE_STOPPED)
 		return -1;
 
 	buffer = (struct queue_cell *) ((char *) q + q->buffer_off);
-	pos = atomic_load_explicit(&q->head, memory_order_relaxed);
+	pos = std::atomic_load_explicit(&q->head, std::memory_order_relaxed);
 	for (;;) {
 		cell = &buffer[pos & q->buffer_mask];
-		seq = atomic_load_explicit(&cell->sequence, memory_order_acquire);
+		seq = std::atomic_load_explicit(&cell->sequence, std::memory_order_acquire);
 		diff = (intptr_t) seq - (intptr_t) (pos + 1);
 
 		if (diff == 0) {
-			if (atomic_compare_exchange_weak_explicit(&q->head, &pos, pos + 1, memory_order_relaxed, memory_order_relaxed))
+			if (atomic_compare_exchange_weak_explicit(&q->head, &pos, pos + 1, std::memory_order_relaxed, std::memory_order_relaxed))
 				break;
 		}
 		else if (diff < 0)
 			return 0;
 		else
-			pos = atomic_load_explicit(&q->head, memory_order_relaxed);
+			pos = std::atomic_load_explicit(&q->head, std::memory_order_relaxed);
 	}
 
 	*ptr = (char *) q + cell->data_off;
-	atomic_store_explicit(&cell->sequence, pos + q->buffer_mask + 1, memory_order_release);
+	std::atomic_store_explicit(&cell->sequence, pos + q->buffer_mask + 1, std::memory_order_release);
 
 	return 1;
 }
@@ -187,7 +187,7 @@ int queue_pull_many(struct queue *q, void *ptr[], size_t cnt)
 int queue_close(struct queue *q)
 {
 	enum state expected = STATE_INITIALIZED;
-	if (atomic_compare_exchange_weak_explicit(&q->state, &expected, STATE_STOPPED, memory_order_relaxed, memory_order_relaxed))
+	if (std::atomic_compare_exchange_weak_explicit(&q->state, &expected, STATE_STOPPED, std::memory_order_relaxed, std::memory_order_relaxed))
 		return 0;
 
 	return -1;
diff --git a/lib/queue_signalled.c b/lib/queue_signalled.cpp
similarity index 98%
rename from lib/queue_signalled.c
rename to lib/queue_signalled.cpp
index ae7962ff5..d66b89cde 100644
--- a/lib/queue_signalled.c
+++ b/lib/queue_signalled.cpp
@@ -31,7 +31,7 @@
 
 static void queue_signalled_cleanup(void *p)
 {
-	struct queue_signalled *qs = p;
+	struct queue_signalled *qs = (struct queue_signalled *) p;
 
 	if (qs->mode == QUEUE_SIGNALLED_PTHREAD)
 		pthread_mutex_unlock(&qs->pthread.mutex);
@@ -41,7 +41,7 @@ int queue_signalled_init(struct queue_signalled *qs, size_t size, struct memory_
 {
 	int ret;
 
-	qs->mode = flags & QUEUE_SIGNALLED_MASK;
+	qs->mode = (enum queue_signalled_flags) (flags & QUEUE_SIGNALLED_MASK);
 
 	if (qs->mode == 0) {
 #ifdef __linux__
diff --git a/lib/sample.c b/lib/sample.cpp
similarity index 97%
rename from lib/sample.c
rename to lib/sample.cpp
index 1ec9c089c..9e6d16b80 100644
--- a/lib/sample.c
+++ b/lib/sample.cpp
@@ -46,9 +46,9 @@ struct sample * sample_alloc(struct pool *p)
 {
 	struct sample *s;
 
-	s = pool_get(p);
+	s = (struct sample *) pool_get(p);
 	if (!s)
-		return NULL;
+		return nullptr;
 
 	s->pool_off = (char *) p - (char *) s;
 
@@ -61,9 +61,9 @@ struct sample * sample_alloc_mem(int capacity)
 {
 	size_t sz = SAMPLE_LENGTH(capacity);
 
-	char *b = alloc(sz);
+	char *b = (char *) alloc(sz);
 	if (!b)
-		return NULL;
+		return nullptr;
 
 	struct sample *s = (struct sample *) b;
 
@@ -166,11 +166,11 @@ struct sample * sample_clone(struct sample *orig)
 
 	pool = sample_pool(orig);
 	if (!pool)
-		return NULL;
+		return nullptr;
 
 	clone = sample_alloc(pool);
 	if (!clone)
-		return NULL;
+		return nullptr;
 
 	sample_copy(clone, orig);
 
@@ -234,7 +234,7 @@ int sample_cmp(struct sample *a, struct sample *b, double epsilon, int flags)
 			return 4;
 		}
 
-		for (int i = 0; i < a->length; i++) {
+		for (unsigned i = 0; i < a->length; i++) {
 			/* Compare format */
 			if (sample_format(a, i) != sample_format(b, i))
 				return 6;
diff --git a/lib/shmem.c b/lib/shmem.cpp
similarity index 94%
rename from lib/shmem.c
rename to lib/shmem.cpp
index 6482c3bf9..1a1c70bec 100644
--- a/lib/shmem.c
+++ b/lib/shmem.cpp
@@ -87,20 +87,19 @@ retry:	fd = shm_open(wname, O_RDWR|O_CREAT|O_EXCL, 0600);
 	if (ftruncate(fd, len) < 0)
 		return -1;
 
-	base = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+	base = mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 	if (base == MAP_FAILED)
 		return -4;
 
 	close(fd);
 
 	manager = memory_managed(base, len);
-	shared = memory_alloc(manager, sizeof(struct shmem_shared));
+	shared = (struct shmem_shared *) memory_alloc(manager, sizeof(struct shmem_shared));
 	if (!shared) {
 		errno = ENOMEM;
 		return -5;
 	}
 
-	memset(shared, 0, sizeof(struct shmem_shared));
 	shared->polling = conf->polling;
 
 	int flags = QUEUE_SIGNALLED_PROCESS_SHARED;
@@ -109,12 +108,14 @@ retry:	fd = shm_open(wname, O_RDWR|O_CREAT|O_EXCL, 0600);
 	else
 		flags |= QUEUE_SIGNALLED_PTHREAD;
 
+	shared->queue.queue.state = STATE_DESTROYED;
 	ret = queue_signalled_init(&shared->queue, conf->queuelen, manager, flags);
 	if (ret) {
 		errno = ENOMEM;
 		return -6;
 	}
 
+	shared->pool.state = STATE_DESTROYED;
 	ret = pool_init(&shared->pool, conf->queuelen, SAMPLE_LENGTH(conf->samplelen), manager);
 	if (ret) {
 		errno = ENOMEM;
@@ -140,7 +141,7 @@ retry:	fd = shm_open(wname, O_RDWR|O_CREAT|O_EXCL, 0600);
 		return -9;
 
 	len = stat_buf.st_size;
-	base = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+	base = mmap(nullptr, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 
 	if (base == MAP_FAILED)
 		return -10;
diff --git a/lib/signal.c b/lib/signal.cpp
similarity index 90%
rename from lib/signal.c
rename to lib/signal.cpp
index e67f0ba75..9660df57d 100644
--- a/lib/signal.c
+++ b/lib/signal.cpp
@@ -32,8 +32,8 @@ int signal_init(struct signal *s)
 {
 	s->enabled = true;
 
-	s->name = NULL;
-	s->unit = NULL;
+	s->name = nullptr;
+	s->unit = nullptr;
 	s->type = SIGNAL_TYPE_INVALID;
 
 	s->refcnt = ATOMIC_VAR_INIT(1);
@@ -72,7 +72,15 @@ int signal_init_from_mapping(struct signal *s, const struct mapping_entry *me, u
 			break;
 
 		case MAPPING_TYPE_DATA:
-			*s = *me->data.signal;
+			s->type = me->data.signal->type;
+			s->init = me->data.signal->init;
+			s->enabled = me->data.signal->enabled;
+
+			if (me->data.signal->name)
+				s->name = strdup(me->data.signal->name);
+
+			if (me->data.signal->unit)
+				s->name = strdup(me->data.signal->unit);
 			break;
 	}
 
@@ -95,13 +103,13 @@ struct signal * signal_create(const char *name, const char *unit, enum signal_ty
 	int ret;
 	struct signal *sig;
 
-	sig = alloc(sizeof(struct signal));
+	sig = (struct signal *) alloc(sizeof(struct signal));
 	if (!sig)
-		return NULL;
+		return nullptr;
 
 	ret = signal_init(sig);
 	if (ret)
-		return NULL;
+		return nullptr;
 
 	if (name)
 		sig->name = strdup(name);
@@ -147,9 +155,9 @@ struct signal * signal_copy(struct signal *s)
 {
 	struct signal *ns;
 
-	ns = alloc(sizeof(struct signal));
+	ns = (struct signal *) alloc(sizeof(struct signal));
 	if (!ns)
-		return NULL;
+		return nullptr;
 
 	signal_init(ns);
 
@@ -170,10 +178,10 @@ int signal_parse(struct signal *s, json_t *cfg)
 {
 	int ret;
 	json_error_t err;
-	json_t *json_init = NULL;
-	const char *name = NULL;
-	const char *unit = NULL;
-	const char *type = NULL;
+	json_t *json_init = nullptr;
+	const char *name = nullptr;
+	const char *unit = nullptr;
+	const char *type = nullptr;
 
 	ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: s, s?: s, s?: o, s?: b }",
 		"name", &name,
@@ -243,7 +251,7 @@ int signal_list_parse(struct vlist *list, json_t *cfg)
 	size_t i;
 	json_t *json_signal;
 	json_array_foreach(cfg, i, json_signal) {
-		s = alloc(sizeof(struct signal));
+		s = (struct signal *) alloc(sizeof(struct signal));
 		if (!s)
 			return -1;
 
@@ -265,10 +273,10 @@ int signal_list_generate(struct vlist *list, unsigned len, enum signal_type typ)
 {
 	char name[32];
 
-	for (int i = 0; i < len; i++) {
+	for (unsigned i = 0; i < len; i++) {
 		snprintf(name, sizeof(name), "signal%d", i);
 
-		struct signal *sig = signal_create(name, NULL, typ);
+		struct signal *sig = signal_create(name, nullptr, typ);
 		if (!sig)
 			return -1;
 
@@ -296,7 +304,7 @@ int signal_list_generate2(struct vlist *list, const char *dt)
 		for (int j = 0; j < len; j++) {
 			snprintf(name, sizeof(name), "signal%d", i++);
 
-			struct signal *sig = signal_create(name, NULL, typ);
+			struct signal *sig = signal_create(name, nullptr, typ);
 			if (!sig)
 				return -1;
 
@@ -307,12 +315,12 @@ int signal_list_generate2(struct vlist *list, const char *dt)
 	return 0;
 }
 
-void signal_list_dump(const struct vlist *list, const union signal_data *data, int len)
+void signal_list_dump(const struct vlist *list, const union signal_data *data, unsigned len)
 {
 	debug(5, "  Signals:");
 
-	for (int i = 0; i < vlist_length(list); i++) {
-		struct signal *sig = vlist_at(list, i);
+	for (size_t i = 0; i < vlist_length(list); i++) {
+		struct signal *sig = (struct signal *) vlist_at(list, i);
 
 		char *buf = strf("    %d:", i);
 
@@ -408,12 +416,12 @@ const char * signal_type_to_str(enum signal_type fmt)
 			return "invalid";
 	}
 
-	return NULL;
+	return nullptr;
 }
 
 enum signal_type signal_type_detect(const char *val)
 {
-	char *brk;
+	const char *brk;
 	int len;
 
 	debug(LOG_IO | 5, "Attempt to detect type of value: %s", val);
@@ -535,15 +543,15 @@ void signal_data_cast(union signal_data *data, const struct signal *from, const
 		case SIGNAL_TYPE_COMPLEX:
 			switch(from->type) {
 				case SIGNAL_TYPE_BOOLEAN:
-					data->z = CMPLXF(data->b, 0);
+					data->z = data->b;
 					break;
 
 				case SIGNAL_TYPE_INTEGER:
-					data->z = CMPLXF(data->i, 0);
+					data->z = data->i;
 					break;
 
 				case SIGNAL_TYPE_FLOAT:
-					data->z = CMPLXF(data->f, 0);
+					data->z = data->f;
 					break;
 
 				case SIGNAL_TYPE_COMPLEX:
@@ -591,7 +599,7 @@ int signal_data_parse_str(union signal_data *data, const struct signal *sig, con
 
 			(*end)++;
 
-			data->z = CMPLXF(real, imag);
+			data->z = real + _Complex_I * imag;
 			break;
 		}
 
@@ -630,7 +638,7 @@ int signal_data_parse_json(union signal_data *data, const struct signal *sig, js
 			if (ret)
 				return -2;
 
-			data->z = CMPLXF(real, imag);
+			data->z = real + _Complex_I * imag;
 			break;
 		}
 
diff --git a/lib/socket_addr.c b/lib/socket_addr.cpp
similarity index 90%
rename from lib/socket_addr.c
rename to lib/socket_addr.cpp
index a57282617..62ef6e1af 100644
--- a/lib/socket_addr.c
+++ b/lib/socket_addr.cpp
@@ -32,7 +32,7 @@
 char * socket_print_addr(struct sockaddr *saddr)
 {
 	union sockaddr_union *sa = (union sockaddr_union *) saddr;
-	char *buf = alloc(64);
+	char *buf = (char *) alloc(64);
 
 	/* Address */
 	switch (sa->sa.sa_family) {
@@ -106,8 +106,8 @@ int socket_parse_address(const char *addr, struct sockaddr *saddr, enum socket_l
 		/* Split string */
 		char *lasts;
 		char *node = strtok_r(copy, "%", &lasts);
-		char *ifname = strtok_r(NULL, ":", &lasts);
-		char *proto = strtok_r(NULL, "\0", &lasts);
+		char *ifname = strtok_r(nullptr, ":", &lasts);
+		char *proto = strtok_r(nullptr, "\0", &lasts);
 
 		/* Parse link layer (MAC) address */
 		struct ether_addr *mac = ether_aton(node);
@@ -123,7 +123,7 @@ int socket_parse_address(const char *addr, struct sockaddr *saddr, enum socket_l
 		if (!link)
 			error("Failed to get network interface: '%s'", ifname);
 
-		sa->sll.sll_protocol = htons(proto ? strtol(proto, NULL, 0) : ETH_P_VILLAS);
+		sa->sll.sll_protocol = htons(proto ? strtol(proto, nullptr, 0) : ETH_P_VILLAS);
 		sa->sll.sll_halen = ETHER_ADDR_LEN;
 		sa->sll.sll_family = AF_PACKET;
 		sa->sll.sll_ifindex = rtnl_link_get_ifindex(link);
@@ -140,18 +140,18 @@ int socket_parse_address(const char *addr, struct sockaddr *saddr, enum socket_l
 		/* Split string */
 		char *lasts;
 		char *node = strtok_r(copy, ":", &lasts);
-		char *service = strtok_r(NULL, "\0", &lasts);
+		char *service = strtok_r(nullptr, "\0", &lasts);
 
 		if (node && !strcmp(node, "*"))
-			node = NULL;
+			node = nullptr;
 
 		if (service && !strcmp(service, "*"))
-			service = NULL;
+			service = nullptr;
 
 		switch (layer) {
 			case SOCKET_LAYER_IP:
 				hint.ai_socktype = SOCK_RAW;
-				hint.ai_protocol = (service) ? strtol(service, NULL, 0) : IPPROTO_VILLAS;
+				hint.ai_protocol = (service) ? strtol(service, nullptr, 0) : IPPROTO_VILLAS;
 				hint.ai_flags |= AI_NUMERICSERV;
 				break;
 
@@ -166,7 +166,7 @@ int socket_parse_address(const char *addr, struct sockaddr *saddr, enum socket_l
 
 		/* Lookup address */
 		struct addrinfo *result;
-		ret = getaddrinfo(node, (layer == SOCKET_LAYER_IP) ? NULL : service, &hint, &result);
+		ret = getaddrinfo(node, (layer == SOCKET_LAYER_IP) ? nullptr : service, &hint, &result);
 		if (!ret) {
 			if (layer == SOCKET_LAYER_IP) {
 				/* We mis-use the sin_port field to store the IP protocol number on RAW sockets */
@@ -188,7 +188,8 @@ int socket_compare_addr(struct sockaddr *x, struct sockaddr *y)
 {
 #define CMP(a, b) if (a != b) return a < b ? -1 : 1
 
-	union sockaddr_union *xu = (void *) x, *yu = (void *) y;
+	union sockaddr_union *xu = (union sockaddr_union *) x;
+	union sockaddr_union *yu = (union sockaddr_union *) y;
 
 	CMP(x->sa_family, y->sa_family);
 
diff --git a/lib/stats.c b/lib/stats.cpp
similarity index 89%
rename from lib/stats.c
rename to lib/stats.cpp
index 2b8334d74..ef4c8aeb1 100644
--- a/lib/stats.c
+++ b/lib/stats.cpp
@@ -23,13 +23,13 @@
 #include <string.h>
 
 #include <villas/stats.h>
-#include <villas/hist.h>
+#include <villas/hist.hpp>
 #include <villas/timing.h>
 #include <villas/node.h>
 #include <villas/utils.h>
 #include <villas/log.h>
 #include <villas/node.h>
-#include <villas/table.h>
+#include <villas/table.hpp>
 
 struct stats_metric_description stats_metrics[] = {
 	{ "skipped",		STATS_METRIC_SMPS_SKIPPED,	"samples",	"Skipped samples and the distance between them" 		},
@@ -144,30 +144,27 @@ void stats_reset(struct stats *s)
 		hist_reset(&s->histograms[i]);
 }
 
-static struct table_column stats_cols[] = {
-	{ 10, "Node",		"%s",	NULL,		TABLE_ALIGN_LEFT },
-	{ 10, "Recv",		"%ju",	"pkts",		TABLE_ALIGN_RIGHT },
-	{ 10, "Sent",		"%ju",	"pkts",		TABLE_ALIGN_RIGHT },
-	{ 10, "Drop",		"%ju",	"pkts",		TABLE_ALIGN_RIGHT },
-	{ 10, "Skip",		"%ju",	"pkts",		TABLE_ALIGN_RIGHT },
-	{ 10, "OWD last",	"%lf",	"secs",		TABLE_ALIGN_RIGHT },
-	{ 10, "OWD mean",	"%lf",	"secs",		TABLE_ALIGN_RIGHT },
-	{ 10, "Rate last",	"%lf",	"pkt/sec",	TABLE_ALIGN_RIGHT },
-	{ 10, "Rate mean",	"%lf",	"pkt/sec",	TABLE_ALIGN_RIGHT },
-	{ 10, "Age mean",	"%lf",	"secs",		TABLE_ALIGN_RIGHT },
-	{ 10, "Age Max",	"%lf",	"sec",		TABLE_ALIGN_RIGHT }
+static std::vector<TableColumn> stats_columns = {
+	{ 10, TableColumn::align::LEFT,		"Node",		"%s"				},
+	{ 10, TableColumn::align::RIGHT,	"Recv",		"%ju",	"pkts"		},
+	{ 10, TableColumn::align::RIGHT,	"Sent",		"%ju",	"pkts"		},
+	{ 10, TableColumn::align::RIGHT,	"Drop",		"%ju",	"pkts"		},
+	{ 10, TableColumn::align::RIGHT,	"Skip",		"%ju",	"pkts"		},
+	{ 10, TableColumn::align::RIGHT,	"OWD last",	"%lf",	"secs"		},
+	{ 10, TableColumn::align::RIGHT,	"OWD mean",	"%lf",	"secs"		},
+	{ 10, TableColumn::align::RIGHT,	"Rate last",	"%lf",	"pkt/sec"	},
+	{ 10, TableColumn::align::RIGHT,	"Rate mean",	"%lf",	"pkt/sec"	},
+	{ 10, TableColumn::align::RIGHT,	"Age mean",	"%lf",	"secs"		},
+	{ 10, TableColumn::align::RIGHT,	"Age Max",	"%lf",	"sec"		}
 };
 
-static struct table stats_table = {
-	.ncols = ARRAY_LEN(stats_cols),
-	.cols = stats_cols
-};
+static Table stats_table = Table(stats_columns);
 
 void stats_print_header(enum stats_format fmt)
 {
 	switch (fmt) {
 		case STATS_FORMAT_HUMAN:
-			table_header(&stats_table);
+			stats_table.header();
 			break;
 
 		default: { }
@@ -180,7 +177,7 @@ void stats_print_periodic(struct stats *s, FILE *f, enum stats_format fmt, struc
 
 	switch (fmt) {
 		case STATS_FORMAT_HUMAN:
-			table_row(&stats_table,
+			stats_table.row(11,
 				node_name_short(n),
 				(uintmax_t) hist_total(&s->histograms[STATS_METRIC_OWD]),
 				(uintmax_t) hist_total(&s->histograms[STATS_METRIC_AGE]),
diff --git a/src/villas-pipe.cpp b/src/villas-pipe.cpp
index b47668861..a4e9a66c9 100644
--- a/src/villas-pipe.cpp
+++ b/src/villas-pipe.cpp
@@ -157,7 +157,7 @@ static void * send_loop(void *ctx)
 		allocated = sample_alloc_many(&dirs->send.pool, smps, node->out.vectorize);
 		if (allocated < 0)
 			throw RuntimeError("Failed to get {} samples out of send pool.", node->out.vectorize);
-		else if (allocated < node->out.vectorize)
+		else if (allocated < (int) node->out.vectorize)
 			logger->warn("Send pool underrun");
 
 		scanned = io_scan(dirs->send.io, smps, allocated);
@@ -219,7 +219,7 @@ static void * recv_loop(void *ctx)
 		allocated = sample_alloc_many(&dirs->recv.pool, smps, node->in.vectorize);
 		if (allocated < 0)
 			throw RuntimeError("Failed to allocate {} samples from receive pool.", node->in.vectorize);
-		else if (allocated < node->in.vectorize)
+		else if (allocated < (int) node->in.vectorize)
 			logger->warn("Receive pool underrun: allocated only {} of {} samples", allocated, node->in.vectorize);
 
 		release = allocated;
diff --git a/src/villas-test-rtt.cpp b/src/villas-test-rtt.cpp
index c06ccb14a..2aad22012 100644
--- a/src/villas-test-rtt.cpp
+++ b/src/villas-test-rtt.cpp
@@ -37,7 +37,7 @@
 #include <villas/log.hpp>
 #include <villas/node.h>
 #include <villas/utils.hpp>
-#include <villas/hist.h>
+#include <villas/hist.hpp>
 #include <villas/timing.h>
 #include <villas/pool.h>
 #include <villas/kernel/rt.hpp>