diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -9,6 +9,8 @@
               with --cpp -traditional flags
   * (1.18.5): fix a bug with windows filepath directory separators in a
               #include
+  * (1.18.6): bugfix to reject a macro usage with different arity than
+              its definition
 
 
 Version 1.17
diff --git a/Language/Preprocessor/Cpphs/HashDefine.hs b/Language/Preprocessor/Cpphs/HashDefine.hs
--- a/Language/Preprocessor/Cpphs/HashDefine.hs
+++ b/Language/Preprocessor/Cpphs/HashDefine.hs
@@ -60,12 +60,18 @@
 expandMacro :: HashDefine -> [String] -> Bool -> String
 expandMacro macro parameters layout =
     let env = zip (arguments macro) parameters
-        replace (Arg,s)  = maybe (error "formal param") id (lookup s env)
-        replace (Str,s)  = maybe (error "formal param") str (lookup s env)
+        replace (Arg,s)  = maybe ("")      id (lookup s env)
+        replace (Str,s)  = maybe (str "") str (lookup s env)
         replace (Text,s) = if layout then s else filter (/='\n') s
         str s = '"':s++"\""
+        checkArity | length (arguments macro) == 1 && length parameters <= 1
+                   || length (arguments macro) == length parameters = id
+                   | otherwise = error ("macro "++name macro++" expected "++
+                                        show (length (arguments macro))++
+                                        " arguments, but was given "++
+                                        show (length parameters))
     in
-    concatMap replace (expansion macro)
+    checkArity $ concatMap replace (expansion macro)
 
 -- | Parse a \#define, or \#undef, ignoring other \# directives
 parseHashDefine :: Bool -> [String] -> Maybe HashDefine
diff --git a/Language/Preprocessor/Cpphs/ReadFirst.hs b/Language/Preprocessor/Cpphs/ReadFirst.hs
--- a/Language/Preprocessor/Cpphs/ReadFirst.hs
+++ b/Language/Preprocessor/Cpphs/ReadFirst.hs
@@ -51,4 +51,3 @@
         if not ok then try ps
           else do content <- readFile file
                   return (file,content)
-
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 LIBRARY = cpphs
-VERSION = 1.18.5
+VERSION = 1.18.6
 
 DIRS	= Language/Preprocessor/Cpphs \
 	  Text/ParserCombinators
diff --git a/README b/README
--- a/README
+++ b/README
@@ -30,7 +30,7 @@
 
 COPYRIGHT
 ---------
-Copyright (c) 2004-2013 Malcolm Wallace (Malcolm.Wallace@me.com)
+Copyright (c) 2004-2014 Malcolm Wallace (Malcolm.Wallace@me.com)
 except for Text.ParserCombinators.HuttonMeijer (Copyright (c) 1995
 Graham Hutton and Erik Meijer).
 
diff --git a/cpphs.cabal b/cpphs.cabal
--- a/cpphs.cabal
+++ b/cpphs.cabal
@@ -1,5 +1,5 @@
 Name: cpphs
-Version: 1.18.5
+Version: 1.18.6
 Copyright: 2004-2014, Malcolm Wallace
 License: LGPL
 License-File: LICENCE-LGPL
diff --git a/cpphs.hs b/cpphs.hs
--- a/cpphs.hs
+++ b/cpphs.hs
@@ -20,7 +20,7 @@
 import Data.List   ( isPrefixOf )
 
 version :: String
-version = "1.18.5"
+version = "1.18.6"
 
 main :: IO ()
 main = do
diff --git a/docs/index.html b/docs/index.html
--- a/docs/index.html
+++ b/docs/index.html
@@ -198,11 +198,11 @@
 <b>Current stable version:</b>
 
 <p>
-cpphs-1.18.5, release date 2014.06.26<br>
+cpphs-1.18.6, release date 2014.10.17<br>
 By HTTP:
 <a href="http://hackage.haskell.org/package/cpphs">Hackage</a>.
 <ul>
-<li> fix a bug related to windows filepath directory separators in #includes
+<li> bugfix to reject a macro usage with different arity than its definition
 </ul>
 
 <p>
@@ -226,6 +226,14 @@
 <b>Older versions:</b>
 
 <p>
+cpphs-1.18.5, release date 2014.06.26<br>
+By HTTP:
+<a href="http://hackage.haskell.org/package/cpphs">Hackage</a>.
+<ul>
+<li> fix a bug related to windows filepath directory separators in #includes
+</ul>
+
+<p>
 cpphs-1.18.4, release date 2014.03.22<br>
 By HTTP:
 <a href="http://hackage.haskell.org/package/cpphs">Hackage</a>.
@@ -688,7 +696,7 @@
         Malcolm.Wallace@me.com</a> 
 </ul>
 
-<p><b>Copyright:</b> &copy; 2004-2012 Malcolm Wallace,
+<p><b>Copyright:</b> &copy; 2004-2014 Malcolm Wallace,
 except for ParseLib (Copyright &copy; 1995 Graham Hutton and Erik Meijer)
 
 <p><b>License:</b> The library modules in cpphs are distributed under
diff --git a/tests/expect29 b/tests/expect29
--- a/tests/expect29
+++ b/tests/expect29
@@ -1,3 +1,7 @@
+Warning: unknown directive #def
+in Test.hsc  at line 6 col 1
+Warning: unknown directive #def
+in Test.hsc  at line 9 col 1
 #line 1 "Test.hsc"
 module Test where
 
diff --git a/tests/expect59 b/tests/expect59
new file mode 100644
--- /dev/null
+++ b/tests/expect59
@@ -0,0 +1,1 @@
+cpphs.exe: macro FOO expected 2 arguments, but was given 1
diff --git a/tests/expect60 b/tests/expect60
new file mode 100644
--- /dev/null
+++ b/tests/expect60
@@ -0,0 +1,8 @@
+#line 1 "wrongarity0"
+
+
+
+
+There is no error here
+
+stringise ""
diff --git a/tests/runtests b/tests/runtests
--- a/tests/runtests
+++ b/tests/runtests
@@ -2,14 +2,27 @@
 CPPHS=${1:-"../cpphs"}
 FAIL=0
 
+# Run a test and report whether it matched the expected output.
 runtest() {
-  if $1 >out 2>/dev/null && dos2unix -q out && diff $2 out >/dev/null
+  if $1 >out 2>&1 && dos2unix -q out && diff $2 out >/dev/null
   then echo "passed: " $1
   else FAIL=$?
        echo "FAILED: ($2) " $1
   fi
 }
 
+# For tests which are expected to fail
+runtestE() {
+  if $1 >out 2>&1 && dos2unix -q out && diff $2 out >/dev/null
+  then echo "UNEXPECTED PASS: ($2) " $1
+  else if dos2unix -q out && diff $2 out >/dev/null
+       then echo "passed: " $1
+       else FAIL=$?
+            echo "FAILED: ($2) " $1
+       fi
+  fi
+}
+
 if $CPPHS </dev/null; then echo -n "passed: "; else echo -n "FAILED: "; fi
 echo " $CPPHS </dev/null"
 runtest "$CPPHS --nomacro testfile" expect1
@@ -76,4 +89,6 @@
 runtest "$CPPHS th" expect56
 runtest "$CPPHS cheplyaka" expect57
 runtest "$CPPHS booleanchain" expect58
+runtestE "$CPPHS wrongarity" expect59
+runtest "$CPPHS --hashes wrongarity0" expect60
 exit $FAIL
diff --git a/tests/tmp b/tests/tmp
--- a/tests/tmp
+++ b/tests/tmp
@@ -1,9 +1,1 @@
-#line 1 "booleanchain"
-
-This file tests the #if boolean expression parser/evaluator.
-
-
-
-
-SUCCEED with not and parens
-
+cpphs.exe: macro FOO expected 2 arguments, but was given 1
diff --git a/tests/wrongarity b/tests/wrongarity
new file mode 100644
--- /dev/null
+++ b/tests/wrongarity
@@ -0,0 +1,5 @@
+#define FOO(x,y) This is fine x y
+
+#if FOO(1)
+There is an error here
+#endif
diff --git a/tests/wrongarity0 b/tests/wrongarity0
new file mode 100644
--- /dev/null
+++ b/tests/wrongarity0
@@ -0,0 +1,7 @@
+#define FOO(x) 1 && 1
+#define BAR(x) stringise #x
+
+#if FOO()
+There is no error here
+#endif
+BAR()
