diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,8 @@
+2022-09-07
+        * Version bump (3.11). (#376)
+        * Update to support language-c99-0.2.0. (#371)
+        * Fix error handling buffers in generated code for 'step'. (#314)
+
 2022-07-07
         * Version bump (3.10). (#356)
         * Remove unnecessary dependencies from Cabal package. (#323)
diff --git a/copilot-c99.cabal b/copilot-c99.cabal
--- a/copilot-c99.cabal
+++ b/copilot-c99.cabal
@@ -1,6 +1,6 @@
 cabal-version             : >= 1.10
 name                      : copilot-c99
-version                   : 3.10
+version                   : 3.11
 synopsis                  : A compiler for Copilot targeting C99.
 description               :
   This package is a back-end from Copilot to C.
@@ -49,9 +49,9 @@
                           , mtl                 >= 2.2 && < 2.4
                           , pretty              >= 1.1 && < 1.2
 
-                          , copilot-core        >= 3.10  && < 3.11
-                          , language-c99        >= 0.1.1 && < 0.2
-                          , language-c99-simple >= 0.1.1 && < 0.2
+                          , copilot-core        >= 3.11  && < 3.12
+                          , language-c99        >= 0.2.0 && < 0.3
+                          , language-c99-simple >= 0.2.2 && < 0.3
 
   exposed-modules         : Copilot.Compile.C99
 
diff --git a/src/Copilot/Compile/C99/CodeGen.hs b/src/Copilot/Compile/C99/CodeGen.hs
--- a/src/Copilot/Compile/C99/CodeGen.hs
+++ b/src/Copilot/Compile/C99/CodeGen.hs
@@ -4,9 +4,10 @@
 -- | High-level translation of Copilot Core into C99.
 module Copilot.Compile.C99.CodeGen where
 
-import Control.Monad.State  (runState)
-import Data.List            (union, unzip4)
-import Data.Typeable        (Typeable)
+import           Control.Monad.State (runState)
+import           Data.List           (union, unzip4)
+import qualified Data.List.NonEmpty  as NonEmpty
+import           Data.Typeable       (Typeable)
 
 import qualified Language.C99.Simple as C
 
@@ -50,7 +51,7 @@
     name     = streamname sid
     cty      = C.Array (transtype ty) (Just $ C.LitInt $ fromIntegral buffsize)
     buffsize = length xs
-    initvals = Just $ C.InitArray $ constarray ty xs
+    initvals = Just $ C.InitList $ constarray ty xs
 
 -- | Make a C index variable and initialise it to 0.
 mkindexdecln :: Id -> C.Decln
@@ -100,14 +101,16 @@
           tmpassign = case ty of
             Array _ -> C.Expr $ memcpy (C.Ident tmp_var) val size
               where
-                size = C.LitInt $ fromIntegral $ tysize ty
+                size = C.LitInt (fromIntegral $ tysize ty)
+                        C..* C.SizeOfType (C.TypeName (tyElemName ty))
             _       -> C.Expr $ C.Ident tmp_var C..= val
 
           bufferupdate = case ty of
             Array _ -> C.Expr $ memcpy dest (C.Ident tmp_var) size
               where
                 dest = C.Index buff_var index_var
-                size = C.LitInt $ fromIntegral $ tysize ty
+                size = C.LitInt (fromIntegral $ tysize ty)
+                         C..* C.SizeOfType (C.TypeName (tyElemName ty))
             _       -> C.Expr $
                            C.Index buff_var index_var C..= (C.Ident tmp_var)
 
@@ -129,7 +132,8 @@
         where
           exvar  = C.Ident cpyname
           locvar = C.Ident name
-          size   = C.LitInt $ fromIntegral $ tysize ty
+          size   = C.LitInt (fromIntegral $ tysize ty)
+                     C..* C.SizeOfType (C.TypeName (tyElemName ty))
 
       _       -> C.Ident cpyname C..= C.Ident name
 
@@ -219,12 +223,22 @@
     memcpy :: C.Expr -> C.Expr -> C.Expr -> C.Expr
     memcpy dest src size = C.Funcall (C.Ident "memcpy") [dest, src, size]
 
+    -- Translate a Copilot type to a C99 type, handling arrays especially.
+    --
+    -- If the given type is an array (including multi-dimensional arrays), the
+    -- type is that of the elements in the array. Otherwise, it is just the
+    -- equivalent representation of the given type in C.
+    tyElemName :: Type a -> C.Type
+    tyElemName ty = case ty of
+      Array ty' -> tyElemName ty'
+      _         -> transtype ty
+
 -- | Write a struct declaration based on its definition.
 mkstructdecln :: Struct a => Type a -> C.Decln
 mkstructdecln (Struct x) = C.TypeDecln struct
   where
     struct = C.TypeSpec $ C.StructDecln (Just $ typename x) fields
-    fields = map mkfield (toValues x)
+    fields = NonEmpty.fromList $ map mkfield (toValues x)
 
     mkfield :: Value a -> C.FieldDecln
     mkfield (Value ty field) = C.FieldDecln (transtype ty) (fieldname field)
diff --git a/src/Copilot/Compile/C99/Translate.hs b/src/Copilot/Compile/C99/Translate.hs
--- a/src/Copilot/Compile/C99/Translate.hs
+++ b/src/Copilot/Compile/C99/Translate.hs
@@ -3,7 +3,8 @@
 -- | Translate Copilot Core expressions and operators to C99.
 module Copilot.Compile.C99.Translate where
 
-import Control.Monad.State
+import           Control.Monad.State
+import qualified Data.List.NonEmpty  as NonEmpty
 
 import Copilot.Core
 import Copilot.Compile.C99.Error (impossible)
@@ -226,7 +227,7 @@
   Float     -> explicitty ty . C.LitFloat
   Double    -> explicitty ty . C.LitDouble
   Struct _  -> \v ->
-    C.InitVal (transtypename ty) (map constfieldinit (toValues v))
+    C.InitVal (transtypename ty) (constStruct (toValues v))
   Array ty' -> \v ->
     C.InitVal (transtypename ty) (constarray ty' (arrayelems v))
 
@@ -254,26 +255,30 @@
   -- whole expression as an array of two int32_t's (as opposed to a nested
   -- array). This can either lead to compile-time errors (if you're lucky) or
   -- incorrect runtime semantics (if you're unlucky).
-  Array ty' -> C.InitArray $ constarray ty' $ arrayelems val
+  Array ty' -> C.InitList $ constarray ty' $ arrayelems val
 
   -- We use InitArray to initialize a struct because the syntax used for
   -- initializing arrays and structs is compatible. For instance, {1, 2} works
   -- both for initializing an int array of length 2 as well as a struct with
   -- two int fields, although the two expressions are conceptually different
-  -- (structs can also be initialized as { .a = 1, .b = 2}, but language-c99
-  -- does not support such syntax and does not provide a specialized
-  -- initialization construct for structs).
-  Struct _  -> C.InitArray $ map constfieldinit $ toValues val
+  -- (structs can also be initialized as { .a = 1, .b = 2}.
+  Struct _  -> C.InitList $ constStruct (toValues val)
   _         -> C.InitExpr $ constty ty val
 
 -- | Transform a Copilot Core struct field into a C99 initializer.
-constfieldinit :: Value a -> C.Init
-constfieldinit (Value ty (Field val)) = constinit ty val
+constfieldinit :: Value a -> C.InitItem
+constfieldinit (Value ty (Field val)) = C.InitItem Nothing $ constinit ty val
 
+-- | Transform a Copilot Struct, based on the struct fields, into a list of C99
+-- initializer values.
+constStruct :: [Value a] -> NonEmpty.NonEmpty C.InitItem
+constStruct val = NonEmpty.fromList $ map constfieldinit val
+
 -- | Transform a Copilot Array, based on the element values and their type,
 -- into a list of C99 initializer values.
-constarray :: Type a -> [a] -> [C.Init]
-constarray ty = map (constinit ty)
+constarray :: Type a -> [a] -> NonEmpty.NonEmpty C.InitItem
+constarray ty =
+  NonEmpty.fromList . map (C.InitItem Nothing . constinit ty)
 
 -- | Explicitly cast a C99 value to a type.
 explicitty :: Type a -> C.Expr -> C.Expr
