diff --git a/rtree-c/src/ReduceC.hs b/rtree-c/src/ReduceC.hs
index 50dc3be1bd85fb7890fd0a480a47a8177e548971..f2bcefc9cd5aae81c8ec2cd282e19780aad58b35 100644
--- a/rtree-c/src/ReduceC.hs
+++ b/rtree-c/src/ReduceC.hs
@@ -415,8 +415,9 @@ updateCDerivedDeclarators bt ff dd = do
     C.CPtrDeclr _ _ -> do
       pure (NonVoid . TPointer $ t, d : dd')
     C.CArrDeclr r as ni -> do
+      ctx <- get
       d' <- case as of
-        C.CArrSize _ _ -> do
+        C.CArrSize _ _ | not (DontReduceArrays `isIn` ctx) -> do
           b <- check ("remove array size", C.posOf ni)
           pure $ if b then C.CArrDeclr r (C.CNoArrSize False) ni else d
         _ -> pure d
@@ -567,9 +568,9 @@ reduceCExternalDeclaration r = case r of
     isStatic <- case forceStatic of
       Just t -> pure t
       Nothing ->
-        if any isStaticSpec spec
+        if any isStaticSpec spec && not (DontRemoveStatic `isIn` ctx)
           then not <$> check ("make declaration non-static", C.posOf ni)
-          else return False
+          else return True
 
     ctx' <- get
     (bt, spec') <- joinLiftMaybe $ updateCDeclarationSpecifiers keepAll{sfKeepStatic = isStatic} ctx' spec
@@ -792,7 +793,7 @@ reduceCInitializer t einit ctx toplevel = case einit of
           r' <- reduceCInitializer t' r ctx False
           pure (p, r')
       TPointer (NonVoid t')
-        | toplevel -> do
+        | toplevel && not (DontReduceArrays `isIn` ctx) -> do
             items' <- reverseRemoveList ni2 (reverse items)
             forM (reverse items') \(p, r) -> do
               r' <- reduceCInitializer t' r ctx False
@@ -1476,8 +1477,9 @@ data Keyword
   | ComputeFunctionFixpoint
   | InlineTypeDefs
   | InitializeVariables
-  | NoSemantics
   | AllowEmptyDeclarations
+  | DontReduceArrays
+  | DontRemoveStatic
   | DisallowVariableInlining
   | AllowInfiniteForLoops
   deriving (Show, Read, Enum, Eq, Ord)