diff --git a/compiler/CS_CodeGen.jrag b/compiler/CS_CodeGen.jrag
index 9c6278a23f55af2e8c06c28f6ef874e5f127b3dd..c147dc6da26ea3a57bab97c551c31a64aad1a78e 100644
--- a/compiler/CS_CodeGen.jrag
+++ b/compiler/CS_CodeGen.jrag
@@ -645,6 +645,10 @@ aspect CS_Class {
 		    " not declared");
   }
 
+  public boolean VoidType.CS_needInstance() {
+    return false;
+  }
+
   public boolean PrimType.CS_needInstance() {
     return false;
   }
@@ -772,13 +776,15 @@ aspect CS_Info {
 
   public void TypeDecl.CS_info(CS_env env, String namespace) {
     env.print(";C#;typedef;" + namespace + getName() + ";");
-    getType().CS_emitType(env);
+    getType().CS_emitType(env) ;
+    env.print(";not_applicable_for_C#");
     env.println();
   }
 
   public void SampleDecl.CS_info(CS_env env, String namespace) {
     env.print(";C#;sample;" + namespace + getName() + ";");
     getType().CS_emitType(env);
+    env.print(";not_applicable_for_C#");
     env.println();
   }
 
diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag
index 4d4c76b4c7b9f1c754aa5b7119cfe849318ae5f2..e2e04baac6435830a280165aa77d055d512aa071 100644
--- a/compiler/C_CodeGen.jrag
+++ b/compiler/C_CodeGen.jrag
@@ -371,8 +371,10 @@ aspect C_Declarations {
 
     env.println("int labcomm"+env.verStr+"_encode_" + env.prefix + getName() + "(");
     env.indent();
-    env.println("struct labcomm"+env.verStr+"_encoder *e,");
-    env.println(env.prefix + getName() + " *v");
+    env.println("struct labcomm"+env.verStr+"_encoder *e");
+    if(!isVoid() ) {
+        env.println(", "+env.prefix + getName() + " *v");
+    }
     env.unindent();
     env.println(");");
 
@@ -700,8 +702,10 @@ aspect C_Encoder {
     env = env.nestStruct("(*v)");
     env.println("static int encode_" + env.prefix + getName() + "(");
     env.indent();
-    env.println("struct labcomm"+env.verStr+"_writer *w,");
-    env.println(env.prefix + getName() + " *v");
+    env.println("struct labcomm"+env.verStr+"_writer *w");
+    if(!isVoid() ) {
+        env.println(", "+env.prefix + getName() + " *v");
+    }
     env.unindent();
     env.println(")");
     env.println("{");
@@ -714,16 +718,19 @@ aspect C_Encoder {
 
     // Typesafe encode wrapper
     env.println("int labcomm"+env.verStr+"_encode_" + env.prefix + getName() + "(");
-    env.println("struct labcomm"+env.verStr+"_encoder *e,");
-    env.println(env.prefix + getName() + " *v");
+    env.println("struct labcomm"+env.verStr+"_encoder *e");
+    if(!isVoid() ) {
+        env.println(", "+env.prefix + getName() + " *v");
+    }
     env.unindent();
     env.println(")");
     env.println("{");
     env.indent();
     env.println("return labcomm"+env.verStr+"_internal_encode(e, &labcomm"+env.verStr+"_signature_" + 
 		env.prefix + getName() + 
-		", (labcomm"+env.verStr+"_encoder_function)encode_" + env.prefix + getName() +
-		", v);");
+		", (labcomm"+env.verStr+"_encoder_function)encode_" + 
+                env.prefix + getName() +
+		(!isVoid()?", v":", NULL")+");");
     env.unindent();
     env.println("}");
   }
@@ -745,7 +752,7 @@ aspect C_Encoder {
   }
 
   public void UserType.C_emitEncoder(C_env env) {
-    lookupType(getName()).getType().C_emitEncoder(env);
+    decl().getType().C_emitEncoder(env);
   }
 
   public void StructType.C_emitEncoder(C_env env) {
@@ -1156,12 +1163,23 @@ aspect C_Info {
 
   public void TypeDecl.C_info(C_env env) {
     env.println(",C,typedef," + env.prefix + getName() + "," + 
-                 env.prefix + getName());
+                 env.prefix + getName() + "," +
+                 C_info_type_or_void(env.prefix));
   }
 
   public void SampleDecl.C_info(C_env env) {
     env.println(",C,sample," + env.prefix + getName() + "," + 
-                env.prefix + getName());
+                 env.prefix + getName() + "," +
+                 C_info_type_or_void(env.prefix));
   }
 
+  // make void types explicitly as they require special treatment
+  // in encoder/decoder calls
+  protected String Decl.C_info_type_or_void(String prefix) {
+    if(isVoid() ) {
+      return "void";
+    } else {
+      return prefix + getName() ;
+    }
+  }
 }
diff --git a/compiler/DeclNames.jrag b/compiler/DeclNames.jrag
new file mode 100644
index 0000000000000000000000000000000000000000..4e58087cd269406ec4db3970c7cf90a8f2242051
--- /dev/null
+++ b/compiler/DeclNames.jrag
@@ -0,0 +1,7 @@
+aspect DeclNames {
+	inh String Type.declName();
+	eq Decl.getType().declName() = getName();
+
+	inh String Field.declName();
+	eq StructType.getField(int i).declName() = declName();
+}
diff --git a/compiler/ErrorCheck.jrag b/compiler/ErrorCheck.jrag
index b1e255ecdcbc33685fd91e40f7ee2639b9a80587..caa80815456d4c1a390f2f80f7a5a7e5f74c0b8d 100644
--- a/compiler/ErrorCheck.jrag
+++ b/compiler/ErrorCheck.jrag
@@ -20,6 +20,7 @@ aspect ErrorCheck {
 	}
 	public void ASTNode.errorCheck(Collection collection) {
 	    nameCheck();
+            typeCheck();
 	    if(hasErrors())
 		collection.add(errors);
 	    for(int i = 0; i < getNumChild(); i++) {
diff --git a/compiler/Java_CodeGen.jrag b/compiler/Java_CodeGen.jrag
index 7b7aab4844f754cebdeac65f7ec8a9777b304ac8..b01ff8f02e5052fd9979c69ed60bee9e32768586 100644
--- a/compiler/Java_CodeGen.jrag
+++ b/compiler/Java_CodeGen.jrag
@@ -196,6 +196,7 @@ aspect Java_StructName {
 aspect Java_Void {
 
   syn boolean Decl.isVoid() = getType().isVoid();
+  syn boolean UserType.isVoid() = decl().isVoid();
   syn boolean Type.isVoid() = false;
   syn boolean VoidType.isVoid() = true;
 
@@ -746,6 +747,10 @@ aspect Java_Class {
 		    " not declared");
   }
 
+  public boolean VoidType.Java_needInstance() {
+    return false;
+  }
+
   public boolean PrimType.Java_needInstance() {
     return false;
   }
@@ -864,13 +869,15 @@ aspect Java_Info {
 
   public void TypeDecl.Java_info(Java_env env) {
     env.print(",Java,typedef," + getName() + ",");
-    getType().Java_emitType(env);
+    getType().Java_emitType(env); 
+    env.print(",not_applicable_for_Java");
     env.println();
   }
 
   public void SampleDecl.Java_info(Java_env env) {
     env.print(",Java,sample," + getName() + ",");
     getType().Java_emitType(env);
+    env.print(",not_applicable_for_Java");
     env.println();
   }
 
diff --git a/compiler/LabComm.ast b/compiler/LabComm.ast
index 7b11255bac395e1b6d0989d1d45f5231c1850a5c..6f290e58d497c19dc4f78ffb443fe6dd3278944a 100644
--- a/compiler/LabComm.ast
+++ b/compiler/LabComm.ast
@@ -12,7 +12,7 @@ PrimType          : Type ::= <Name:String> <Token:int>;
 UserType          : Type ::= <Name:String>;
 StructType        : Type ::= Field*;
 ParseArrayType    : Type ::= Type Dim*;
-abstract ArrayType : Type ::= Type Exp*;
+abstract ArrayType :Type ::= Type Exp*;
 VariableArrayType : ArrayType;
 FixedArrayType    : ArrayType;
 
diff --git a/compiler/LabComm.java b/compiler/LabComm.java
index c1c7251f9bb622b617d6acf5a1005c6d05eb581d..c86125a5c17df193402c526d6f2d688602632c35 100644
--- a/compiler/LabComm.java
+++ b/compiler/LabComm.java
@@ -249,6 +249,10 @@ public class LabComm {
 	if (prettyOnStdout) {
 	  ast.pp(System.out);
 	}
+      } else {
+          // Catch-all for compilation errors
+          System.err.println("Error in specification");
+          System.exit(3);
       }
     }
   } 
diff --git a/compiler/LabCommParser.parser b/compiler/LabCommParser.parser
index 8bef9036102cb7cc6e5c7bd2a9742cc80b225dd9..dea1194a0c06dc7ce19a9813000d9591c4dc40b3 100644
--- a/compiler/LabCommParser.parser
+++ b/compiler/LabCommParser.parser
@@ -14,7 +14,7 @@
       s.append("  *** Syntactic error: unexpected token " + Terminals.NAMES[token.getId()]);
       throw new SourceError(s.toString());
         //super.syntaxError(token);
-        //throw new RuntimeException(token.getLine(token.getStart()) + ", " + 
+        //throw new RuntimeException(token.getLine(token.getStart()) + ", " +
 	// token.getColumn(token.getStart()) + ": Syntax Error");
     }
     public void scannerError(Scanner.Exception e) {
@@ -55,51 +55,50 @@ List var_decl_list =
 
 Field var_decl =
     type.t IDENTIFIER SEMICOLON     {: return new Field(t, IDENTIFIER); :}
-  | type.t IDENTIFIER dim_list.d SEMICOLON 
+  | type.t IDENTIFIER dim_list.d SEMICOLON
     {: return new Field(new ParseArrayType(t, d), IDENTIFIER); :}
   ;
 
-TypeDecl type_decl = 
+TypeDecl type_decl =
     TYPEDEF type.t IDENTIFIER SEMICOLON {: return new TypeDecl(t, IDENTIFIER); :}
-  | TYPEDEF type.t IDENTIFIER dim_list.d SEMICOLON 
+  | TYPEDEF type.t IDENTIFIER dim_list.d SEMICOLON
     {: return new TypeDecl(new ParseArrayType(t, d), IDENTIFIER); :}
   ;
 
-SampleDecl sample_decl = 
-    SAMPLE type.t IDENTIFIER SEMICOLON 
+SampleDecl sample_decl =
+    SAMPLE type.t IDENTIFIER SEMICOLON
       {: return new SampleDecl(t, IDENTIFIER); :}
-  | SAMPLE type.t IDENTIFIER dim_list.d SEMICOLON 
+  | SAMPLE type.t IDENTIFIER dim_list.d SEMICOLON
       {: return new SampleDecl(new ParseArrayType(t, d), IDENTIFIER); :}
-  | SAMPLE VOID IDENTIFIER SEMICOLON 
-      {: return new SampleDecl(new VoidType(), IDENTIFIER); :}
   ;
 
 Type type =
     prim_type.p                     {: return p; :}
   | user_type.u                     {: return u; :}
   | struct_type.s                   {: return s; :}
+  | void_type.v                     {: return v; :}
   ;
 
-PrimType prim_type =      
-    BOOLEAN                         
+PrimType prim_type =
+    BOOLEAN
       {: return new PrimType(BOOLEAN, ASTNode.LABCOMM_BOOLEAN); :}
-  | BYTE                            
+  | BYTE
       {: return new PrimType(BYTE, ASTNode.LABCOMM_BYTE); :}
-  | SHORT                           
+  | SHORT
       {: return new PrimType(SHORT, ASTNode.LABCOMM_SHORT); :}
-  | INT                             
+  | INT
       {: return new PrimType(INT, ASTNode.LABCOMM_INT); :}
-  | LONG                            
+  | LONG
       {: return new PrimType(LONG, ASTNode.LABCOMM_LONG); :}
-  | FLOAT                           
+  | FLOAT
       {: return new PrimType(FLOAT, ASTNode.LABCOMM_FLOAT); :}
-  | DOUBLE                          
+  | DOUBLE
       {: return new PrimType(DOUBLE, ASTNode.LABCOMM_DOUBLE); :}
-  | STRING                          
+  | STRING
       {: return new PrimType(STRING, ASTNode.LABCOMM_STRING); :}
   ;
 
-UserType user_type =      
+UserType user_type =
     IDENTIFIER                      {: return new UserType(IDENTIFIER); :}
   ;
 
@@ -107,6 +106,10 @@ StructType struct_type =
     STRUCT LBRACE var_decl_list.l RBRACE {: return new StructType(l); :}
   ;
 
+VoidType void_type = 
+    VOID {: return new VoidType(); :} 
+;
+
 List dim_list =
     dim.d                           {: return new List().add(d); :}
   | dim_list.l  dim.d               {: return l.add(d); :}
@@ -121,7 +124,7 @@ List exp_list =
   | exp_list.l COMMA exp.e          {: return l.add(e); :}
   ;
 
-Exp exp = 
+Exp exp =
     INTEGER_LITERAL                 {: return new IntegerLiteral(INTEGER_LITERAL); :}
   | UNDERSCORE                      {: return new VariableSize(); :}
   ;
diff --git a/compiler/TypeCheck.jrag b/compiler/TypeCheck.jrag
new file mode 100644
index 0000000000000000000000000000000000000000..a640ace5098013bef6cad31767a96220aa66b8a7
--- /dev/null
+++ b/compiler/TypeCheck.jrag
@@ -0,0 +1,36 @@
+aspect TypeCheck {
+  public void ASTNode.typeCheck() {
+      // calls to the different type checks to be performed
+      nullTypeCheck();
+  }
+
+// void is not allowed as a field in a struct or an array element
+  
+  syn boolean Type.isNull();
+  eq Type.isNull() = false;
+  eq VoidType.isNull() = true;
+  eq UserType.isNull() = decl().isNull();
+
+  syn boolean TypeDecl.isNull();
+  eq TypeDecl.isNull() = getType().isNull();
+  
+  public void ASTNode.nullTypeCheck() {}
+ 
+  public void Field.nullTypeCheck() {
+    if(getType().isNull()) {
+      error("field " + getName() + " of struct "+ declName()+ " may not be of type void");
+    }
+  }
+
+  public void ParseArrayType.nullTypeCheck() {
+    if(getType().isNull()) {
+      error("elements of array "+declName()+" may not be of type void");
+    }
+  }
+
+  public void ArrayType.nullTypeCheck() {
+    if(getType().isNull()) {
+      error("elements of array "+declName()+" may not be of type void");
+    }
+  }
+} 
diff --git a/examples/simple/Decoder.java b/examples/simple/Decoder.java
index 266b895251b6237ee53777dbc05fb8636e13dfff..4ab97e48fccda695f051157b6eb86d293b700d3f 100644
--- a/examples/simple/Decoder.java
+++ b/examples/simple/Decoder.java
@@ -5,7 +5,7 @@ import java.io.InputStream;
 import se.lth.control.labcomm.LabCommDecoderChannel;
 
 public class Decoder
-  implements theTwoInts.Handler, anotherTwoInts.Handler, IntString.Handler, TwoArrays.Handler, TwoFixedArrays.Handler
+  implements theTwoInts.Handler, anotherTwoInts.Handler, IntString.Handler, TwoArrays.Handler, TwoFixedArrays.Handler, doavoid.Handler
 
 {
 
@@ -20,6 +20,7 @@ public class Decoder
     IntString.register(decoder, this);
     TwoArrays.register(decoder, this);
     TwoFixedArrays.register(decoder, this);
+    doavoid.register(decoder, this);
 
     try {
       System.out.println("Running decoder.");
@@ -72,6 +73,10 @@ public class Decoder
     }
     System.out.println();
   }
+  public void handle_doavoid() throws java.io.IOException {
+    System.out.println("Got doavoid");
+  }
+
 
 
   public static void main(String[] arg) throws Exception {
diff --git a/examples/simple/example_encoder.c b/examples/simple/example_encoder.c
index 174694237cfeb83c05093a73bbdf56e8f513a4ad..ea77e11ca026daa100b5b19d6c8449d72c1ba6cf 100644
--- a/examples/simple/example_encoder.c
+++ b/examples/simple/example_encoder.c
@@ -20,9 +20,13 @@ int main(int argc, char *argv[]) {
 				labcomm_default_error_handler, 
 				labcomm_default_memory,
 				labcomm_default_scheduler);
+  labcomm_encoder_register_simple_doavoid(encoder);
   labcomm_encoder_register_simple_theTwoInts(encoder);
   labcomm_encoder_register_simple_anotherTwoInts(encoder);
   labcomm_encoder_register_simple_IntString(encoder);
+
+  labcomm_encode_simple_doavoid(encoder);
+
   simple_IntString is;
   is.x = 24;
   is.s = "Hello, LabComm!";
diff --git a/examples/simple/simple.lc b/examples/simple/simple.lc
index 518395755eda152f137213ae8ab86fed14434f16..f25295d4d5e45c6fd9cb703fea483ab949281405 100644
--- a/examples/simple/simple.lc
+++ b/examples/simple/simple.lc
@@ -25,3 +25,18 @@ sample struct {
   int a[2];
   int b[2,3];
 } TwoFixedArrays;
+
+typedef void avoid;
+
+sample avoid doavoid;
+
+// examples of errors: void may not be used
+// in structs or arrays
+//
+// sample struct {
+//  int a;
+//  avoid error;
+//} foo;
+//
+//sample void error2[2] ;
+//sample avoid error3[_];
diff --git a/examples/twoway/client.c b/examples/twoway/client.c
index 484b20edcabd2f7a2daef7b786d26846de61e9e9..be82e9a8834e45e43eca6964b567d0ac1ef7cb61 100644
--- a/examples/twoway/client.c
+++ b/examples/twoway/client.c
@@ -175,7 +175,7 @@ int main(int argc, char *argv[])
     }
   }
   printf("\n");
-  labcomm_encode_types_Terminate(encoder, LABCOMM_VOID);
+  labcomm_encode_types_Terminate(encoder);
 out:
   return 0;
   
diff --git a/lib/c/test/test_labcomm_generated_encoding.c b/lib/c/test/test_labcomm_generated_encoding.c
index 79aeb4307575f6d6d98f6c9a2215e80eb340e05d..670b8247472c127839eaabf6340e438d538d6c81 100644
--- a/lib/c/test/test_labcomm_generated_encoding.c
+++ b/lib/c/test/test_labcomm_generated_encoding.c
@@ -179,7 +179,8 @@ void dump_encoder(struct labcomm_encoder *encoder)
 
 int main(void)
 {
-  generated_encoding_V V;
+  //no longer used
+  //generated_encoding_V V;
   generated_encoding_B B = 1;
 
   struct labcomm_encoder *encoder = labcomm_encoder_new(
@@ -199,7 +200,8 @@ int main(void)
   EXPECT({0x02, -1, 0x01, 'B', 0x21});
 
   labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
-  labcomm_encode_generated_encoding_V(encoder, &V);
+  // was: labcomm_encode_generated_encoding_V(encoder, &V);
+  labcomm_encode_generated_encoding_V(encoder);
   EXPECT({-1});
 
   labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
diff --git a/test/Makefile b/test/Makefile
index 7401102eba4792c16788f41379678faca4fae516..376949f2cec1c70850223cc952f2b87692aeda2d 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,12 +1,12 @@
 TESTS=basic simple nested
 LABCOMM_JAR=../compiler/labComm.jar
-LABCOMM=java -jar $(LABCOMM_JAR) 
+LABCOMM=java -jar $(LABCOMM_JAR)
 
 CFLAGS=-O3 -g -Wall -Werror
 
-all:	
+all:
 
-test: $(TESTS:%=test_%)
+test: $(TESTS:%=test_%) compiler_errors
 #	PYTHONPATH=../lib/python \
 #		./test_encoder_decoder.py --labcomm="$(LABCOMM)" basic.lc
 
@@ -14,12 +14,12 @@ test: $(TESTS:%=test_%)
 clean distclean:
 	rm -rf gen
 
-.PHONY: test_%
+.PHONY: test_% 
 test_%: gen/%/signatures.py \
 	gen/%/c_relay \
 	gen/%/cs_relay.exe \
 	gen/%/java_relay.class \
-	gen/%/java_code 
+	gen/%/java_code
 	PYTHONPATH=../lib/python ./test_encoder_decoder.py \
 		--signatures=gen/$*/signatures.py \
 		--test tee gen/$*/testdata \
@@ -27,6 +27,20 @@ test_%: gen/%/signatures.py \
 		--test mono gen/$*/cs_relay.exe /dev/stdin /dev/stdout \
 		--test java \\-cp gen/$*:../lib/java/labcomm.jar java_relay \
 			    /dev/stdin /dev/stdout
+
+# test cases for compiler error checking
+.PHONY: compiler_errors testErrorsOK testErrorsNOK
+
+compiler_errors: testErrorsOK testErrorsNOK
+
+# tests that should succeed
+testErrorsOK: $(wildcard errors/correct/*.lc)
+	./test_errors.py --labcomm="$(LABCOMM)" --testOK $^
+
+# tests that should fail
+testErrorsNOK: $(wildcard errors/incorrect/*.lc)
+	./test_errors.py --labcomm="$(LABCOMM)" --testNOK $^
+
 .PRECIOUS: gen/%/.dir
 gen/%/.dir:
 	mkdir -p gen/$*
@@ -52,7 +66,7 @@ gen/%/c_relay.c: gen/%/typeinfo relay_gen_c.py Makefile
 .PRECIOUS: gen/%/c_relay
 gen/%/c_relay: gen/%/c_relay.c gen/%/c_code.c Makefile
 	$(CC) $(CFLAGS) -o $@ $< -I../lib/c -I. -L..//lib/c \
-		gen/$*/c_code.c -llabcomm 
+		gen/$*/c_code.c -llabcomm
 
 # C# relay test rules
 .PRECIOUS: gen/%/cs_code.cs
diff --git a/test/errors/correct/structtype.lc b/test/errors/correct/structtype.lc
new file mode 100644
index 0000000000000000000000000000000000000000..9eef504d7e0421baa6dad5bf83cfe6ad22f7d04c
--- /dev/null
+++ b/test/errors/correct/structtype.lc
@@ -0,0 +1,9 @@
+typedef struct {
+	string topic;
+} pubsub;
+
+sample pubsub subscribe;
+sample pubsub unsubscribe;
+
+sample pubsub publish;
+sample pubsub unpublish;
diff --git a/test/errors/correct/void.lc b/test/errors/correct/void.lc
new file mode 100644
index 0000000000000000000000000000000000000000..a2d8a8470b94de9ebb1b047d9845ddd907a9f754
--- /dev/null
+++ b/test/errors/correct/void.lc
@@ -0,0 +1,14 @@
+typedef void avoid;
+
+sample avoid doavoid;
+
+// examples of errors: void may not be used
+// in structs or arrays
+//
+// sample struct {
+//  int a;
+//  avoid error;
+//} foo;
+//
+//sample void error2[2] ;
+//sample avoid error3[_];
diff --git a/test/errors/incorrect/void.lc b/test/errors/incorrect/void.lc
new file mode 100644
index 0000000000000000000000000000000000000000..743c4d05836e41ae049c54dbd1051818e90dfc51
--- /dev/null
+++ b/test/errors/incorrect/void.lc
@@ -0,0 +1,12 @@
+typedef void avoid;
+
+// examples of errors: void may not be used
+// in structs or arrays
+//
+sample struct {
+  int a;
+  avoid error_1;
+} foo;
+
+sample void error_2[2] ;
+sample avoid error_3[_];
diff --git a/test/relay_gen_c.py b/test/relay_gen_c.py
index 6f4da2ca1b7e1d621a5e52d0e7e1052c33edbb3b..837cf7243b0c4ac383b43b6ad93cf5f1cdd15757 100755
--- a/test/relay_gen_c.py
+++ b/test/relay_gen_c.py
@@ -16,13 +16,14 @@ if __name__ == '__main__':
     f = open(sys.argv[1])
     sample = []
     for l in map(lambda s: s.strip(), f):
-        lang,kind,func,arg = l[1:].split(l[0])
+        lang,kind,func,arg,stype = l[1:].split(l[0])
         if lang == 'C' and kind == 'sample':
-            sample.append((func, arg))
+            sample.append((func, arg, stype))
             pass
         pass
     result = []
     result.extend(split_match('^[^|]*\|(.*)$', """
+      |// generated by relay_gen_c.py
       |#include <sys/types.h>
       |#include <sys/stat.h>
       |#include <fcntl.h>
@@ -34,13 +35,19 @@ if __name__ == '__main__':
       |#include <labcomm_fd_writer.h>
       |#include "c_code.h"
     """))
-    for func,arg in sample:
+    for func,arg,stype in sample:
         result.extend(split_match('^[^|]*\|(.*)$', """
           |void handle_%(func)s(%(arg)s *v, void *context)
           |{
           |  struct labcomm_encoder *e = context;
-          |  labcomm_encode_%(func)s(e, v);
-          |}""" % { 'func': func, 'arg': arg }))
+          |  labcomm_encode_%(func)s(e%(valargstr)s);
+          |}""" % { 'func': func, 'arg': arg, 'valargstr': '' if stype == "void" else', v' }))
+#        result.extend(split_match('^[^|]*\|(.*)$', """
+#          |void handle_%(func)s(%(arg)s *v, void *context)
+#          |{
+#          |  struct labcomm_encoder *e = context;
+#          |  labcomm_encode_%(func)s(e, v);
+#          |}""" % { 'func': func, 'arg': arg }))
         pass
     result.extend(split_match('^[^|]*\|(.*)$', """
       |int main(int argc, char *argv[]) {
@@ -64,7 +71,7 @@ if __name__ == '__main__':
       |                           labcomm_default_memory,
       |                           labcomm_default_scheduler);
     """))
-    for func,arg in sample:
+    for func,arg,stype in sample:
         result.extend(split_match('^[^|]*\|(.*)$', """
           |  labcomm_encoder_register_%(func)s(e);
           |  labcomm_decoder_register_%(func)s(d, handle_%(func)s, e);
diff --git a/test/relay_gen_cs.py b/test/relay_gen_cs.py
index 06a4e659507c21cf82071af63c1aad66abffb435..68fdc4de6db96a45ae1d75fc263fd3ebc498aafe 100755
--- a/test/relay_gen_cs.py
+++ b/test/relay_gen_cs.py
@@ -16,7 +16,7 @@ if __name__ == '__main__':
     f = open(sys.argv[1])
     sample = []
     for l in map(lambda s: s.strip(), f):
-        lang,kind,func,arg = l[1:].split(l[0])
+        lang,kind,func,arg,dummy = l[1:].split(l[0])
         if lang == 'C#' and kind == 'sample':
             sample.append((func, arg))
             pass
diff --git a/test/relay_gen_java.py b/test/relay_gen_java.py
index 9c0869bbac9fcb143051897784603655be27c27f..93644bc2ed679087264766594acece7467f04eaf 100755
--- a/test/relay_gen_java.py
+++ b/test/relay_gen_java.py
@@ -16,7 +16,7 @@ if __name__ == '__main__':
     f = open(sys.argv[1])
     sample = []
     for l in map(lambda s: s.strip(), f):
-        lang,kind,func,arg = l[1:].split(l[0])
+        lang,kind,func,arg,dummy = l[1:].split(l[0])
         if lang == 'Java' and kind == 'sample':
             sample.append((func, arg))
             pass
diff --git a/test/test_errors.py b/test/test_errors.py
new file mode 100755
index 0000000000000000000000000000000000000000..24b9627cd07b6aa0abacf7d131609dfa7ef16fe2
--- /dev/null
+++ b/test/test_errors.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+
+import sys
+import argparse
+import subprocess
+
+# returns true if test fails
+def test_labcomm_compile_OK(lc, args):
+    cmd = args.labcomm.split() + [lc]
+    try:
+        res = subprocess.check_call(cmd)
+        print "sucess!"
+        return False
+    except subprocess.CalledProcessError as ex:
+        print ex.output
+        print ex.returncode
+        return True
+
+def test_labcomm_compile_fail(lc, args):
+    cmd = args.labcomm.split() + [lc]
+    try:
+        res = subprocess.check_call(cmd)
+        print "failed! (should have produced an error)"
+        return True
+    except subprocess.CalledProcessError as ex:
+        print "sucess!"
+        print ex.output
+        print ex.returncode
+        return False;
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(description='Run test of error messages.')
+
+    parser.add_argument('--labcomm');
+    parser.add_argument('--testOK', nargs='*', default=[])
+    parser.add_argument('--testNOK', nargs='*', default=[])
+    args = parser.parse_args()
+
+    fail = False;
+    for test in args.testOK:
+        fail = fail or test_labcomm_compile_OK(test, args)
+        pass
+    for test in args.testNOK:
+        fail = fail or test_labcomm_compile_fail(test, args)
+        pass
+    if fail:
+        print "*** fail ***"
+    else:
+        print "*** success ***"