diff --git a/src/c_wrapper/event.cpp b/src/c_wrapper/event.cpp
index fd388523f5588871568627a0427a7a41218ba2c6..c59fb3fc41848c1e925b09d2d6b393548ee30c3d 100644
--- a/src/c_wrapper/event.cpp
+++ b/src/c_wrapper/event.cpp
@@ -79,7 +79,7 @@ event::get_profiling_info(cl_profiling_info param) const
 void
 event::wait()
 {
-    pyopencl_call_guarded(clWaitForEvents, buf_arg<ArgType::Length>(data()));
+    pyopencl_call_guarded(clWaitForEvents, len_arg(data()));
     finished();
 }
 
diff --git a/src/c_wrapper/function.h b/src/c_wrapper/function.h
index 4277f730f25194433b398f94c9133e563f7ab868..70f9909b7c87bbd0592e1234201c2abb8e715a38 100644
--- a/src/c_wrapper/function.h
+++ b/src/c_wrapper/function.h
@@ -14,6 +14,8 @@ namespace pyopencl {
 
 template<typename T>
 using rm_ref_t = typename std::remove_reference<T>::type;
+template<typename T>
+using rm_const_t = typename std::remove_const<T>::type;
 template<bool B, class T = void>
 using enable_if_t = typename std::enable_if<B, T>::type;
 
diff --git a/src/c_wrapper/program.cpp b/src/c_wrapper/program.cpp
index e5fd8da9e22058ab97944e3a9faeb2a86a4fc30e..87611fb4f805ce372692d9c724b23f3231541190 100644
--- a/src/c_wrapper/program.cpp
+++ b/src/c_wrapper/program.cpp
@@ -101,15 +101,22 @@ program::get_build_info(const device *dev, cl_program_build_info param) const
 // Import all the names in pyopencl namespace for c wrappers.
 using namespace pyopencl;
 
+typedef cl_program (*_clCreateProgramWithSourceType)(
+    cl_context, cl_uint, const char* const*, const size_t*, cl_int*);
+
+const static _clCreateProgramWithSourceType _clCreateProgramWithSource =
+    reinterpret_cast<_clCreateProgramWithSourceType>(clCreateProgramWithSource);
+
 // Program
 error*
-create_program_with_source(clobj_t *prog, clobj_t _ctx, const char *src)
+create_program_with_source(clobj_t *prog, clobj_t _ctx, const char *_src)
 {
     auto ctx = static_cast<context*>(_ctx);
     return c_handle_error([&] {
-            size_t length = strlen(src);
+            const auto &src = _src;
+            const size_t length = strlen(src);
             cl_program result = pyopencl_call_guarded(
-                clCreateProgramWithSource, ctx, 1, &src, &length);
+                _clCreateProgramWithSource, ctx, len_arg(src), buf_arg(length));
             *prog = new_program(result, KND_SOURCE);
         });
 }
diff --git a/src/c_wrapper/utils.h b/src/c_wrapper/utils.h
index 5409dc296ba4b54d5aa995b5d467e4b2a2ca911a..f1b24740cec824f6b79f372a6010fc08330a0ecb 100644
--- a/src/c_wrapper/utils.h
+++ b/src/c_wrapper/utils.h
@@ -29,6 +29,15 @@ tostring(const T& v)
 
 namespace pyopencl {
 
+template<typename T, class = void>
+struct CLGenericArgPrinter {
+    static PYOPENCL_INLINE void
+    print(std::ostream &stm, T &arg)
+    {
+        stm << arg;
+    }
+};
+
 PYOPENCL_USE_RESULT static PYOPENCL_INLINE void*
 cl_memdup(const void *p, size_t size)
 {
@@ -60,7 +69,7 @@ _print_buf_content(std::ostream &stm, const T *p, size_t len)
         stm << "[";
     }
     for (size_t i = 0;i < len;i++) {
-        stm << p[i];
+        CLGenericArgPrinter<const T>::print(stm, p[i]);
         if (i != len - 1) {
             stm << ", ";
         }
@@ -93,9 +102,10 @@ print_buf(std::ostream &stm, const T *p, size_t len,
         bool need_quote = content || arg_type != ArgType::None;
         if (content) {
             _print_buf_content(stm, p, len);
+            stm << " ";
         }
         if (need_quote) {
-            stm << " <";
+            stm << "<";
         }
         switch (arg_type) {
         case ArgType::SizeOf:
@@ -138,16 +148,6 @@ extern template void print_buf<cl_image_format>(std::ostream&,
                                                 const cl_image_format*, size_t,
                                                 ArgType, bool, bool);
 
-// TODO
-template<typename T, class = void>
-struct CLGenericArgPrinter {
-    static PYOPENCL_INLINE void
-    print(std::ostream &stm, T &arg)
-    {
-        stm << arg;
-    }
-};
-
 template<>
 struct CLGenericArgPrinter<std::nullptr_t, void> {
     static PYOPENCL_INLINE void
@@ -158,8 +158,9 @@ struct CLGenericArgPrinter<std::nullptr_t, void> {
 };
 
 template<typename T>
-struct CLGenericArgPrinter<T, enable_if_t<std::is_same<const char*, T>::value ||
-                                          std::is_same<char*, T>::value> > {
+struct CLGenericArgPrinter<
+    T, enable_if_t<std::is_same<const char*, rm_const_t<T> >::value ||
+                   std::is_same<char*, rm_const_t<T> >::value> > {
     static PYOPENCL_INLINE void
     print(std::ostream &stm, const char *str)
     {
@@ -252,6 +253,13 @@ size_arg(T &&buf) -> decltype(buf_arg<ArgType::SizeOf>(std::forward<T>(buf)))
     return buf_arg<ArgType::SizeOf>(std::forward<T>(buf));
 }
 
+template<typename T>
+static PYOPENCL_INLINE auto
+len_arg(T &&buf) -> decltype(buf_arg<ArgType::Length>(std::forward<T>(buf)))
+{
+    return buf_arg<ArgType::Length>(std::forward<T>(buf));
+}
+
 template<typename Buff, class = void>
 struct _ArgBufferConverter;
 
@@ -464,7 +472,7 @@ struct _ToArgBuffer<AT, T, enable_if_t<is_pyopencl_buf<T>::value &&
 
 template<typename Buff>
 using __pyopencl_buf_arg_type =
-    rm_ref_t<decltype(buf_arg<ArgType::Length>(std::declval<Buff&>()))>;
+    rm_ref_t<decltype(len_arg(std::declval<Buff&>()))>;
 
 template<typename Buff>
 class CLArg<Buff, enable_if_t<is_pyopencl_buf<Buff>::value> >
@@ -474,7 +482,7 @@ class CLArg<Buff, enable_if_t<is_pyopencl_buf<Buff>::value> >
 public:
     PYOPENCL_INLINE
     CLArg(Buff &buff) noexcept
-        : CLArg<BufType>(m_buff), m_buff(buf_arg<ArgType::Length>(buff))
+        : CLArg<BufType>(m_buff), m_buff(len_arg(buff))
     {}
     PYOPENCL_INLINE
     CLArg(CLArg<Buff> &&other) noexcept