Fix Cython warnings
diff --git a/pyjson5.pyx b/pyjson5.pyx
index 0a147bc..6daa79a 100644
--- a/pyjson5.pyx
+++ b/pyjson5.pyx
@@ -1,5 +1,5 @@
 # distutils: language = c++
-# cython: embedsignature = True, language_level = 3
+# cython: embedsignature = True, language_level = 3, warn.undeclared = True, warn.unreachable = True, warn.maybe_uninitialized = True
 
 include 'src/_imports.pyx'
 include 'src/_constants.pyx'
diff --git a/src/_decoder.pyx b/src/_decoder.pyx
index 03606da..6309c10 100644
--- a/src/_decoder.pyx
+++ b/src/_decoder.pyx
@@ -15,9 +15,6 @@
     cdef boolean seen_asterisk = False
     cdef Py_ssize_t comment_start = _reader_tell(reader)
 
-    comment_start = _reader_tell(reader)
-
-    seen_asterisk = False
     while True:
         if expect(not _reader_good(reader), False):
             break
@@ -38,7 +35,7 @@
 # -1: exhausted
 # -2: exception
 cdef int32_t _skip_to_data_sub(ReaderRef reader, uint32_t c0) except -2:
-    cdef int32_t c1
+    cdef int32_t c1 = 0  # silence warning
     cdef boolean seen_slash
 
     seen_slash = False
@@ -142,7 +139,6 @@
 cdef int32_t _get_escape_sequence(ReaderRef reader,
                                   Py_ssize_t start) except 0x7ffffff:
     cdef uint32_t c0
-    cdef uint32_t c1
 
     c0 = _reader_get(reader)
     if expect(not _reader_good(reader), False):
@@ -246,7 +242,7 @@
 cdef object _decode_number_leading_zero(ReaderRef reader, StackHeapString[char] &buf,
                                         int32_t *c_in_out, Py_ssize_t start):
     cdef uint32_t c0
-    cdef int32_t c1
+    cdef int32_t c1 = 0  # silence warning
 
     if not _reader_good(reader):
         c_in_out[0] = -1
@@ -271,7 +267,7 @@
         buf.push_back(b'\0')
         try:
             return PyLong_FromString(buf.data(), NULL, 16)
-        except Exception as ex:
+        except Exception:
             _raise_unclosed('NumericLiteral', start)
     elif c0 == b'.':
         buf.push_back(b'0')
@@ -294,7 +290,7 @@
         buf.push_back(b'\0')
         try:
             return PyOS_string_to_double(buf.data(), NULL, NULL)
-        except Exception as ex:
+        except Exception:
             _raise_unclosed('NumericLiteral', start)
     elif _is_e(c0):
         while True:
@@ -355,7 +351,7 @@
             return PyOS_string_to_double(buf.data(), NULL, NULL)
         else:
             return PyLong_FromString(buf.data(), NULL, 10)
-    except Exception as ex:
+    except Exception:
         _raise_unclosed('NumericLiteral', start)
 
 
@@ -495,13 +491,14 @@
     )
 
 
-cdef boolean _decode_object(ReaderRef reader, dict result) except False:
+cdef boolean _decode_object(ReaderRef reader, object result) except False:
     cdef int32_t c0
     cdef uint32_t c1
     cdef Py_ssize_t start
     cdef boolean done
     cdef object key
     cdef object value
+    cdef object ex
 
     start = _reader_tell(reader)
 
@@ -558,12 +555,13 @@
     return False
 
 
-cdef boolean _decode_array(ReaderRef reader, list result) except False:
+cdef boolean _decode_array(ReaderRef reader, object result) except False:
     cdef int32_t c0
     cdef uint32_t c1
     cdef Py_ssize_t start
     cdef boolean done
     cdef object value
+    cdef object ex
 
     start = _reader_tell(reader)
 
@@ -646,26 +644,30 @@
 
 
 cdef object _decode_recursive_enter(ReaderRef reader, int32_t *c_in_out):
+    cdef boolean (*fn)(ReaderRef reader, object result) except False
     cdef object result
     cdef int32_t c0
     cdef uint32_t c1
+    cdef object ex
 
     c0 = c_in_out[0]
     c1 = cast_to_uint32(c0)
 
+    if c1 == b'{':
+        result = {}
+        fn = _decode_object
+    else:
+        result = []
+        fn = _decode_array
+
     _reader_enter(reader)
     try:
-        if c1 == b'{':
-            result = {}
-            _decode_object(reader, result)
-        else:
-            result = []
-            _decode_array(reader, result)
+        fn(reader, result)
     except RecursionError:
         _raise_nesting(_reader_tell(reader), result)
     except _DecoderException as ex:
         (<_DecoderException> ex).result = result
-        raise ex
+        raise
     finally:
         _reader_leave(reader)
 
@@ -711,6 +713,7 @@
     cdef int32_t c0
     cdef uint32_t c1
     cdef object result
+    cdef object ex
 
     start = _reader_tell(reader)
     c0 = _skip_to_data(reader)
@@ -734,20 +737,21 @@
             _raise_unframed_data(c1, start)
     except _DecoderException as ex:
         (<_DecoderException> ex).result = result
-        raise ex
+        raise
 
     return result
 
 
 cdef object _decode_all(ReaderRef reader, boolean some):
-    cdef Exception ex_result
-    cdef _DecoderException ex
+    cdef object ex
     try:
         return _decode_all_sub(reader, some)
-    except _DecoderException as e:
-        ex = <_DecoderException> e
-        ex_result = ex.cls(ex.msg, ex.result, ex.extra)
-    raise ex_result
+    except _DecoderException as ex:
+        raise (<_DecoderException> ex).cls(
+            (<_DecoderException> ex).msg,
+            (<_DecoderException> ex).result,
+            (<_DecoderException> ex).extra,
+        )
 
 
 cdef object _decode_ucs1(const void *string, Py_ssize_t length,
@@ -799,7 +803,7 @@
 cdef object _decode_buffer(Py_buffer &view, int32_t wordlength,
                            Py_ssize_t maxdepth, boolean some):
     cdef object (*decoder)(const void*, Py_ssize_t, Py_ssize_t, boolean)
-    cdef Py_ssize_t length
+    cdef Py_ssize_t length = 0
 
     if wordlength == 1:
         decoder = _decode_ucs1
@@ -813,6 +817,8 @@
     else:
         _raise_illegal_wordlength(wordlength)
         __builtin_unreachable()
+        length = 0
+        decoder = NULL
 
     return decoder(view.buf, length, maxdepth, some)
 
diff --git a/src/_encoder.pyx b/src/_encoder.pyx
index 0fe6780..b2807cc 100644
--- a/src/_encoder.pyx
+++ b/src/_encoder.pyx
@@ -145,6 +145,8 @@
 cdef boolean _append_ascii(WriterRef writer, object data) except False:
     cdef Py_buffer view
     cdef const char *buf
+    cdef Py_ssize_t index
+    cdef unsigned char c
 
     if PyUnicode_Check(data):
         PyUnicode_READY(data)
@@ -156,7 +158,7 @@
         try:
             buf = <const char*> view.buf
             for index in range(view.len):
-                c = buf[index]
+                c = <unsigned char> buf[index]
                 if c & ~0x7f:
                     raise TypeError('Expected ASCII data')
 
@@ -274,7 +276,7 @@
 
 
 cdef boolean _encode_datetime(WriterRef writer, object data) except False:
-    cdef Py_ssize_t length
+    cdef Py_ssize_t length = 0  # silence warning
     cdef object stringified = data.isoformat()
     cdef const char *string = PyUnicode_AsUTF8AndSize(stringified, &length)
 
@@ -288,7 +290,7 @@
 
 cdef boolean _encode_format_string(WriterRef writer, object data, object formatter_string) except False:
     cdef const char *string
-    cdef Py_ssize_t length
+    cdef Py_ssize_t length = 0  # silence warning
 
     if expect(formatter_string is None, False):
         _raise_unstringifiable(data)
diff --git a/src/_encoder_options.pyx b/src/_encoder_options.pyx
index 32e2c48..70b44f4 100644
--- a/src/_encoder_options.pyx
+++ b/src/_encoder_options.pyx
@@ -121,7 +121,6 @@
     ``()`` if ``False`` was specified.
     '''
 
-
     def __reduce__(self):
         '''
         Pickling is not supported (yet).
@@ -135,8 +134,8 @@
         raise NotImplementedError
 
     def __repr__(self):
-        repr_options = _options_from_ascii(self)
-        repr_cls = (
+        cdef object repr_options = _options_from_ascii(self)
+        cdef object repr_cls = (
             ''
             if self.mappingtypes == DEFAULT_MAPPINGTYPES else
             repr(DEFAULT_MAPPINGTYPES)
diff --git a/src/_exports.pyx b/src/_exports.pyx
index 4a1136f..d04cf77 100644
--- a/src/_exports.pyx
+++ b/src/_exports.pyx
@@ -1,3 +1,5 @@
+global DEFAULT_MAX_NESTING_LEVEL, __version__, __all__
+
 DEFAULT_MAX_NESTING_LEVEL = 32
 '''
 Maximum nesting level of data to decode if no ``maxdepth`` argument is specified.
@@ -291,7 +293,7 @@
         Apostrophes ``"'"`` are encoded as ``"\\u0027"``, less-than,
         greater-than, and ampersand likewise.
     '''
-    cdef void *temp = NULL
+    cdef void *temp
     cdef object result
     cdef Py_ssize_t start = (
         <Py_ssize_t> <void*> &(<AsciiObject*> NULL).data[0]
@@ -368,7 +370,7 @@
     bytes
         see `encode(...) <pyjson5.encode_>`_
     '''
-    cdef void *temp = NULL
+    cdef void *temp
     cdef object result
     cdef Py_ssize_t start = (
         <Py_ssize_t> <void*> &(<PyBytesObject*> NULL).ob_sval[0]