diff --git a/src/c_wrapper/clhelper.h b/src/c_wrapper/clhelper.h
index 2c7f66b9db2272e2b5637861a0e7f05a909e02ab..11c3c9d7ad3540379fb37476adb3d76892342ab7 100644
--- a/src/c_wrapper/clhelper.h
+++ b/src/c_wrapper/clhelper.h
@@ -54,7 +54,7 @@ convert_opaque_array_info(T &&buf)
 {
     generic_info info;
     info.dontfree = 0;
-    info.opaque_class = CLObj::get_class_t();
+    info.opaque_class = CLObj::class_id;
     info.type = _copy_str(std::string("void*[") + tostring(buf.len()) + "]");
     info.value = buf_to_base<CLObj>(std::forward<T>(buf)).release();
     return info;
@@ -73,7 +73,7 @@ get_opaque_info(cl_int (*func)(ArgTypes...), const char *name,
                  &param_value, nullptr);
     generic_info info;
     info.dontfree = 0;
-    info.opaque_class = CLObj::get_class_t();
+    info.opaque_class = CLObj::class_id;
     info.type = "void *";
     if (param_value) {
         info.value = (void*)(new CLObj(param_value, /*retain*/ true));
@@ -194,11 +194,10 @@ public:
     PYOPENCL_INLINE void
     print(std::ostream &stm)
     {
-        // TODO
         if (!out) {
             stm << &m_clobj;
         } else {
-            stm << *m_ret << "<" << m_clobj << ">";
+            stm << CLObj::class_name << "(" << *m_ret << ")<" << m_clobj << ">";
         }
     }
 };
diff --git a/src/c_wrapper/clobj.h b/src/c_wrapper/clobj.h
index 1591359e586cd3e9cb0fc4336eadd75d9471596f..4846f26f0cbf9319e235e169608a2589224de7f0 100644
--- a/src/c_wrapper/clobj.h
+++ b/src/c_wrapper/clobj.h
@@ -3,12 +3,9 @@
 #ifndef __PYOPENCL_CLOBJ_H
 #define __PYOPENCL_CLOBJ_H
 
-#define PYOPENCL_DEF_CL_CLASS(name)             \
-    static PYOPENCL_INLINE class_t              \
-    get_class_t()                               \
-    {                                           \
-        return CLASS_##name;                    \
-    }
+#define PYOPENCL_DEF_CL_CLASS(name)                     \
+    constexpr static class_t class_id = CLASS_##name;   \
+    constexpr static const char *class_name = #name;
 
 namespace pyopencl {
 
@@ -51,8 +48,7 @@ template<typename CLObj>
 static PYOPENCL_INLINE void
 _print_clobj(std::ostream &stm, CLObj *obj)
 {
-    // TODO
-    stm << obj << "<" << obj->data() << ">";
+    stm << CLObj::class_name << "(" << obj << ")<" << obj->data() << ">";
 }
 
 template<typename CLObj>
@@ -63,7 +59,6 @@ class CLArg<CLObj,
 private:
     CLObj &m_obj;
 public:
-    constexpr static bool is_out = false;
     CLArg(CLObj &obj) : m_obj(obj)
     {
     }
@@ -88,7 +83,6 @@ class CLArg<CLObj*,
 private:
     CLObj *m_obj;
 public:
-    constexpr static bool is_out = false;
     CLArg(CLObj *obj) : m_obj(obj)
     {
     }
diff --git a/src/c_wrapper/memory_map.h b/src/c_wrapper/memory_map.h
index ac7bdc17dd597a7ee343dfa26c4ab9c6442d5809..714a451dad08432ff8bcf307440dd60b8ab9c43a 100644
--- a/src/c_wrapper/memory_map.h
+++ b/src/c_wrapper/memory_map.h
@@ -19,6 +19,7 @@ private:
     command_queue m_queue;
     memory_object m_mem;
 public:
+    constexpr static const char *class_name = "MEMORY_MAP";
     PYOPENCL_INLINE
     memory_map(const command_queue *queue, const memory_object *mem, void *ptr)
         : clobj(ptr), m_valid(true), m_queue(*queue), m_mem(*mem)
diff --git a/src/c_wrapper/memory_object.h b/src/c_wrapper/memory_object.h
index 07f17d583e7d86428abd595f82f378a406040296..42c60bc157ee8e124c6f0f4d1b35d18afe92ae21 100644
--- a/src/c_wrapper/memory_object.h
+++ b/src/c_wrapper/memory_object.h
@@ -14,6 +14,7 @@ class memory_object : public clobj<cl_mem> {
 private:
     mutable volatile std::atomic_bool m_valid;
 public:
+    constexpr static const char *class_name = "MEMORY_OBJECT";
     PYOPENCL_INLINE
     memory_object(cl_mem mem, bool retain)
         : clobj(mem), m_valid(true)