diff --git a/AST.cpp b/AST.cpp
index 761427db4..a18785ae1 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -77,6 +77,9 @@ void ContractDefinition::checkTypeRequirements()
 	for (ASTPointer<FunctionDefinition> const& function: getDefinedFunctions())
 		function->checkTypeRequirements();
 
+	for (ASTPointer<VariableDeclaration> const& variable: m_stateVariables)
+		variable->checkTypeRequirements();
+
 	// check for hash collisions in function signatures
 	set<FixedHash<4>> hashes;
 	for (auto const& it: getInterfaceFunctionList())
@@ -294,6 +297,12 @@ bool VariableDeclaration::isLValue() const
 	return !isExternalFunctionParameter();
 }
 
+void VariableDeclaration::checkTypeRequirements()
+{
+	if (m_value)
+		m_value->checkTypeRequirements();
+}
+
 bool VariableDeclaration::isExternalFunctionParameter() const
 {
 	auto const* function = dynamic_cast<FunctionDefinition const*>(getScope());
@@ -390,26 +399,26 @@ void Return::checkTypeRequirements()
 	m_expression->expectType(*m_returnParameters->getParameters().front()->getType());
 }
 
-void VariableDefinition::checkTypeRequirements()
+void VariableDeclarationStatement::checkTypeRequirements()
 {
 	// Variables can be declared without type (with "var"), in which case the first assignment
 	// sets the type.
 	// Note that assignments before the first declaration are legal because of the special scoping
 	// rules inherited from JavaScript.
-	if (m_value)
+	if (m_variable->getValue())
 	{
 		if (m_variable->getType())
-			m_value->expectType(*m_variable->getType());
+			m_variable->getValue()->expectType(*m_variable->getType());
 		else
 		{
 			// no type declared and no previous assignment, infer the type
-			m_value->checkTypeRequirements();
-			TypePointer type = m_value->getType();
+			m_variable->getValue()->checkTypeRequirements();
+			TypePointer type = m_variable->getValue()->getType();
 			if (type->getCategory() == Type::Category::IntegerConstant)
 			{
 				auto intType = dynamic_pointer_cast<IntegerConstantType const>(type)->getIntegerType();
 				if (!intType)
-					BOOST_THROW_EXCEPTION(m_value->createTypeError("Invalid integer constant " + type->toString()));
+					BOOST_THROW_EXCEPTION(m_variable->getValue()->createTypeError("Invalid integer constant " + type->toString()));
 				type = intType;
 			}
 			else if (type->getCategory() == Type::Category::Void)
@@ -418,7 +427,6 @@ void VariableDefinition::checkTypeRequirements()
 		}
 	}
 }
-
 void Assignment::checkTypeRequirements()
 {
 	m_leftHandSide->checkTypeRequirements();
diff --git a/AST.h b/AST.h
index 64dac594d..c7fd068d9 100644
--- a/AST.h
+++ b/AST.h
@@ -432,14 +432,17 @@ class VariableDeclaration: public Declaration
 {
 public:
 	VariableDeclaration(Location const& _location, ASTPointer<TypeName> const& _type,
-						ASTPointer<ASTString> const& _name, Visibility _visibility,
-						bool _isStateVar = false, bool _isIndexed = false):
-		Declaration(_location, _name, _visibility), m_typeName(_type),
-		m_isStateVariable(_isStateVar), m_isIndexed(_isIndexed) {}
+							ASTPointer<ASTString> const& _name, ASTPointer<Expression> _value,
+							Visibility _visibility,
+							bool _isStateVar = false, bool _isIndexed = false):
+			Declaration(_location, _name, _visibility),
+			m_typeName(_type), m_value(_value),
+			m_isStateVariable(_isStateVar), m_isIndexed(_isIndexed) {}
 	virtual void accept(ASTVisitor& _visitor) override;
 	virtual void accept(ASTConstVisitor& _visitor) const override;
 
 	TypeName const* getTypeName() const { return m_typeName.get(); }
+	ASTPointer<Expression> const& getValue() const { return m_value; }
 
 	/// Returns the declared or inferred type. Can be an empty pointer if no type was explicitly
 	/// declared and there is no assignment to the variable that fixes the type.
@@ -447,6 +450,9 @@ public:
 	void setType(std::shared_ptr<Type const> const& _type) { m_type = _type; }
 
 	virtual bool isLValue() const override;
+
+	/// Checks that all parameters have allowed types and calls checkTypeRequirements on the body.
+	void checkTypeRequirements();
 	bool isLocalVariable() const { return !!dynamic_cast<FunctionDefinition const*>(getScope()); }
 	bool isExternalFunctionParameter() const;
 	bool isStateVariable() const { return m_isStateVariable; }
@@ -457,6 +463,7 @@ protected:
 
 private:
 	ASTPointer<TypeName> m_typeName;    ///< can be empty ("var")
+	ASTPointer<Expression> m_value;		///< the assigned value, can be missing
 	bool m_isStateVariable;             ///< Whether or not this is a contract state variable
 	bool m_isIndexed;                   ///< Whether this is an indexed variable (used by events).
 
@@ -833,22 +840,20 @@ private:
  * also be "var") but the actual assignment can be missing.
  * Examples: var a = 2; uint256 a;
  */
-class VariableDefinition: public Statement
+class VariableDeclarationStatement: public Statement
 {
 public:
-	VariableDefinition(Location const& _location, ASTPointer<VariableDeclaration> _variable,
-					   ASTPointer<Expression> _value):
-		Statement(_location), m_variable(_variable), m_value(_value) {}
+	VariableDeclarationStatement(Location const& _location, ASTPointer<VariableDeclaration> _variable):
+		Statement(_location), m_variable(_variable) {}
 	virtual void accept(ASTVisitor& _visitor) override;
 	virtual void accept(ASTConstVisitor& _visitor) const override;
 	virtual void checkTypeRequirements() override;
 
 	VariableDeclaration const& getDeclaration() const { return *m_variable; }
-	Expression const* getExpression() const { return m_value.get(); }
+	Expression const* getExpression() const { return m_variable->getValue().get(); }
 
 private:
 	ASTPointer<VariableDeclaration> m_variable;
-	ASTPointer<Expression> m_value; ///< the assigned value, can be missing
 };
 
 /**
diff --git a/ASTForward.h b/ASTForward.h
index 0b6817e45..3a151b63e 100644
--- a/ASTForward.h
+++ b/ASTForward.h
@@ -63,7 +63,7 @@ class ForStatement;
 class Continue;
 class Break;
 class Return;
-class VariableDefinition;
+class VariableDeclarationStatement;
 class ExpressionStatement;
 class Expression;
 class Assignment;
diff --git a/ASTJsonConverter.cpp b/ASTJsonConverter.cpp
index 04feafe2f..c30e4ca2b 100644
--- a/ASTJsonConverter.cpp
+++ b/ASTJsonConverter.cpp
@@ -198,7 +198,7 @@ bool ASTJsonConverter::visit(Return const&)
 	return true;
 }
 
-bool ASTJsonConverter::visit(VariableDefinition const&)
+bool ASTJsonConverter::visit(VariableDeclarationStatement const&)
 {
 	addJsonNode("VariableDefinition", {}, true);
 	return true;
@@ -394,7 +394,7 @@ void ASTJsonConverter::endVisit(Return const&)
 	goUp();
 }
 
-void ASTJsonConverter::endVisit(VariableDefinition const&)
+void ASTJsonConverter::endVisit(VariableDeclarationStatement const&)
 {
 	goUp();
 }
diff --git a/ASTJsonConverter.h b/ASTJsonConverter.h
index 466801e9c..30a92e66c 100644
--- a/ASTJsonConverter.h
+++ b/ASTJsonConverter.h
@@ -64,7 +64,7 @@ public:
 	bool visit(Continue const& _node) override;
 	bool visit(Break const& _node) override;
 	bool visit(Return const& _node) override;
-	bool visit(VariableDefinition const& _node) override;
+	bool visit(VariableDeclarationStatement const& _node) override;
 	bool visit(ExpressionStatement const& _node) override;
 	bool visit(Expression const& _node) override;
 	bool visit(Assignment const& _node) override;
@@ -98,7 +98,7 @@ public:
 	void endVisit(Continue const&) override;
 	void endVisit(Break const&) override;
 	void endVisit(Return const&) override;
-	void endVisit(VariableDefinition const&) override;
+	void endVisit(VariableDeclarationStatement const&) override;
 	void endVisit(ExpressionStatement const&) override;
 	void endVisit(Expression const&) override;
 	void endVisit(Assignment const&) override;
diff --git a/ASTPrinter.cpp b/ASTPrinter.cpp
index d380b0029..aead6abd8 100644
--- a/ASTPrinter.cpp
+++ b/ASTPrinter.cpp
@@ -225,7 +225,7 @@ bool ASTPrinter::visit(Return const& _node)
 	return goDeeper();
 }
 
-bool ASTPrinter::visit(VariableDefinition const& _node)
+bool ASTPrinter::visit(VariableDeclarationStatement const& _node)
 {
 	writeLine("VariableDefinition");
 	printSourcePart(_node);
@@ -469,7 +469,7 @@ void ASTPrinter::endVisit(Return const&)
 	m_indentation--;
 }
 
-void ASTPrinter::endVisit(VariableDefinition const&)
+void ASTPrinter::endVisit(VariableDeclarationStatement const&)
 {
 	m_indentation--;
 }
diff --git a/ASTPrinter.h b/ASTPrinter.h
index d9072aacc..7a0ef5a65 100644
--- a/ASTPrinter.h
+++ b/ASTPrinter.h
@@ -68,7 +68,7 @@ public:
 	bool visit(Continue const& _node) override;
 	bool visit(Break const& _node) override;
 	bool visit(Return const& _node) override;
-	bool visit(VariableDefinition const& _node) override;
+	bool visit(VariableDeclarationStatement const& _node) override;
 	bool visit(ExpressionStatement const& _node) override;
 	bool visit(Expression const& _node) override;
 	bool visit(Assignment const& _node) override;
@@ -109,7 +109,7 @@ public:
 	void endVisit(Continue const&) override;
 	void endVisit(Break const&) override;
 	void endVisit(Return const&) override;
-	void endVisit(VariableDefinition const&) override;
+	void endVisit(VariableDeclarationStatement const&) override;
 	void endVisit(ExpressionStatement const&) override;
 	void endVisit(Expression const&) override;
 	void endVisit(Assignment const&) override;
diff --git a/ASTVisitor.h b/ASTVisitor.h
index a7fa6b1cf..2ecfbe4b1 100644
--- a/ASTVisitor.h
+++ b/ASTVisitor.h
@@ -69,7 +69,7 @@ public:
 	virtual bool visit(Continue&) { return true; }
 	virtual bool visit(Break&) { return true; }
 	virtual bool visit(Return&) { return true; }
-	virtual bool visit(VariableDefinition&) { return true; }
+	virtual bool visit(VariableDeclarationStatement&) { return true; }
 	virtual bool visit(ExpressionStatement&) { return true; }
 	virtual bool visit(Expression&) { return true; }
 	virtual bool visit(Assignment&) { return true; }
@@ -112,7 +112,7 @@ public:
 	virtual void endVisit(Continue&) { }
 	virtual void endVisit(Break&) { }
 	virtual void endVisit(Return&) { }
-	virtual void endVisit(VariableDefinition&) { }
+	virtual void endVisit(VariableDeclarationStatement&) { }
 	virtual void endVisit(ExpressionStatement&) { }
 	virtual void endVisit(Expression&) { }
 	virtual void endVisit(Assignment&) { }
@@ -159,7 +159,7 @@ public:
 	virtual bool visit(Continue const&) { return true; }
 	virtual bool visit(Break const&) { return true; }
 	virtual bool visit(Return const&) { return true; }
-	virtual bool visit(VariableDefinition const&) { return true; }
+	virtual bool visit(VariableDeclarationStatement const&) { return true; }
 	virtual bool visit(ExpressionStatement const&) { return true; }
 	virtual bool visit(Expression const&) { return true; }
 	virtual bool visit(Assignment const&) { return true; }
@@ -202,7 +202,7 @@ public:
 	virtual void endVisit(Continue const&) { }
 	virtual void endVisit(Break const&) { }
 	virtual void endVisit(Return const&) { }
-	virtual void endVisit(VariableDefinition const&) { }
+	virtual void endVisit(VariableDeclarationStatement const&) { }
 	virtual void endVisit(ExpressionStatement const&) { }
 	virtual void endVisit(Expression const&) { }
 	virtual void endVisit(Assignment const&) { }
diff --git a/AST_accept.h b/AST_accept.h
index b71e103df..217a565f0 100644
--- a/AST_accept.h
+++ b/AST_accept.h
@@ -475,24 +475,24 @@ void ExpressionStatement::accept(ASTConstVisitor& _visitor) const
 	_visitor.endVisit(*this);
 }
 
-void VariableDefinition::accept(ASTVisitor& _visitor)
+void VariableDeclarationStatement::accept(ASTVisitor& _visitor)
 {
 	if (_visitor.visit(*this))
 	{
 		m_variable->accept(_visitor);
-		if (m_value)
-			m_value->accept(_visitor);
+		if (m_variable->getValue())
+			m_variable->getValue()->accept(_visitor);
 	}
 	_visitor.endVisit(*this);
 }
 
-void VariableDefinition::accept(ASTConstVisitor& _visitor) const
+void VariableDeclarationStatement::accept(ASTConstVisitor& _visitor) const
 {
 	if (_visitor.visit(*this))
 	{
 		m_variable->accept(_visitor);
-		if (m_value)
-			m_value->accept(_visitor);
+		if (m_variable->getValue())
+			m_variable->getValue()->accept(_visitor);
 	}
 	_visitor.endVisit(*this);
 }
diff --git a/Compiler.cpp b/Compiler.cpp
index 14acc0113..f552210f4 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -73,7 +73,7 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract, Comp
 		for (ASTPointer<InheritanceSpecifier> const& base: contract->getBaseContracts())
 		{
 			ContractDefinition const* baseContract = dynamic_cast<ContractDefinition const*>(
-													base->getName()->getReferencedDeclaration());
+						base->getName()->getReferencedDeclaration());
 			solAssert(baseContract, "");
 			if (baseArguments.count(baseContract) == 0)
 				baseArguments[baseContract] = &base->getArguments();
@@ -85,12 +85,14 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract, Comp
 	{
 		ContractDefinition const* base = bases[bases.size() - i];
 		solAssert(base, "");
+		initializeStateVariables(*base);
 		FunctionDefinition const* baseConstructor = base->getConstructor();
 		if (!baseConstructor)
 			continue;
 		solAssert(baseArguments[base], "");
 		appendBaseConstructorCall(*baseConstructor, *baseArguments[base]);
 	}
+	initializeStateVariables(_contract);
 	if (_contract.getConstructor())
 		appendConstructorCall(*_contract.getConstructor());
 
@@ -247,6 +249,16 @@ void Compiler::registerStateVariables(ContractDefinition const& _contract)
 			m_context.addStateVariable(*variable);
 }
 
+void Compiler::initializeStateVariables(ContractDefinition const& _contract)
+{
+	for(ASTPointer<VariableDeclaration> const& variable: _contract.getStateVariables())
+		if (variable->getValue())
+		{
+			compileExpression(*(variable->getValue()), (variable->getValue())->getType());
+			ExpressionCompiler::appendStateVariableInitialization(m_context, *variable);
+		}
+}
+
 bool Compiler::visit(VariableDeclaration const& _variableDeclaration)
 {
 	solAssert(_variableDeclaration.isStateVariable(), "Compiler visit to non-state variable declaration.");
@@ -429,7 +441,7 @@ bool Compiler::visit(Return const& _return)
 	return false;
 }
 
-bool Compiler::visit(VariableDefinition const& _variableDefinition)
+bool Compiler::visit(VariableDeclarationStatement const& _variableDefinition)
 {
 	if (Expression const* expression = _variableDefinition.getExpression())
 	{
diff --git a/Compiler.h b/Compiler.h
index 1aeaee88f..0838512ee 100644
--- a/Compiler.h
+++ b/Compiler.h
@@ -59,6 +59,7 @@ private:
 	void appendReturnValuePacker(TypePointers const& _typeParameters);
 
 	void registerStateVariables(ContractDefinition const& _contract);
+	void initializeStateVariables(ContractDefinition const& _contract);
 
 	virtual bool visit(VariableDeclaration const& _variableDeclaration) override;
 	virtual bool visit(FunctionDefinition const& _function) override;
@@ -68,7 +69,7 @@ private:
 	virtual bool visit(Continue const& _continue) override;
 	virtual bool visit(Break const& _break) override;
 	virtual bool visit(Return const& _return) override;
-	virtual bool visit(VariableDefinition const& _variableDefinition) override;
+	virtual bool visit(VariableDeclarationStatement const& _variableDefinition) override;
 	virtual bool visit(ExpressionStatement const& _expressionStatement) override;
 	virtual bool visit(PlaceholderStatement const&) override;
 
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index a8bc53e0f..74dfb2b5e 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -56,6 +56,19 @@ void ExpressionCompiler::appendStateVariableAccessor(CompilerContext& _context,
 	compiler.appendStateVariableAccessor(_varDecl);
 }
 
+void ExpressionCompiler::appendStateVariableInitialization(CompilerContext& _context, VariableDeclaration const& _varDecl, bool _optimize)
+{
+	ExpressionCompiler compiler(_context, _optimize);
+	compiler.appendStateVariableInitialization(_varDecl);
+}
+
+void ExpressionCompiler::appendStateVariableInitialization(VariableDeclaration const& _varDecl)
+{
+	m_currentLValue.fromStateVariable(_varDecl);
+	m_currentLValue.storeValue(*_varDecl.getType(), _varDecl.getLocation());
+	m_currentLValue.reset();
+}
+
 bool ExpressionCompiler::visit(Assignment const& _assignment)
 {
 	_assignment.getRightHandSide().accept(*this);
@@ -77,7 +90,6 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
 	}
 	m_currentLValue.storeValue(*_assignment.getRightHandSide().getType(), _assignment.getLocation());
 	m_currentLValue.reset();
-
 	return false;
 }
 
@@ -1018,12 +1030,24 @@ void ExpressionCompiler::LValue::fromIdentifier(Identifier const& _identifier, D
 		m_dataType = _identifier.getType();
 		solAssert(m_dataType->getStorageSize() <= numeric_limits<unsigned>::max(),
 				  "The storage size of " + m_dataType->toString() + " should fit in an unsigned");
-		m_size = unsigned(m_dataType->getStorageSize());	}
+		m_size = unsigned(m_dataType->getStorageSize());
+	}
 	else
 		BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_identifier.getLocation())
 													  << errinfo_comment("Identifier type not supported or identifier not found."));
 }
 
+void ExpressionCompiler::LValue::fromStateVariable(VariableDeclaration const& _declaration)
+{
+	solAssert(m_context->isStateVariable(&_declaration), "Not a state variable.");
+	*m_context << m_context->getStorageLocationOfVariable(_declaration);
+	m_type = LValueType::Storage;
+	m_dataType = _declaration.getType();
+	solAssert(m_dataType->getStorageSize() <= numeric_limits<unsigned>::max(),
+			  "The storage size of " + m_dataType->toString() + " should fit in an unsigned");
+	m_size = unsigned(m_dataType->getStorageSize());
+}
+
 void ExpressionCompiler::LValue::retrieveValue(Location const& _location, bool _remove) const
 {
 	switch (m_type)
@@ -1117,7 +1141,7 @@ void ExpressionCompiler::LValue::storeValue(Type const& _sourceType, Location co
 		}
 		else
 		{
-			solAssert(_sourceType.getCategory() == m_dataType->getCategory(), "");
+			solAssert(_sourceType.getCategory() == m_dataType->getCategory(), "Wrong type conversation for assignment.");
 			if (m_dataType->getCategory() == Type::Category::ByteArray)
 			{
 				CompilerUtils(*m_context).copyByteArrayToStorage(
diff --git a/ExpressionCompiler.h b/ExpressionCompiler.h
index 471d81865..3567a9148 100644
--- a/ExpressionCompiler.h
+++ b/ExpressionCompiler.h
@@ -59,6 +59,9 @@ public:
 	/// Appends code for a State Variable accessor function
 	static void appendStateVariableAccessor(CompilerContext& _context, VariableDeclaration const& _varDecl, bool _optimize = false);
 
+	/// Appends code for a State Variable Initialization function
+	static void appendStateVariableInitialization(CompilerContext& _context, VariableDeclaration const& _varDecl, bool _optimize = false);
+
 private:
 	explicit ExpressionCompiler(CompilerContext& _compilerContext, bool _optimize = false):
 		m_optimize(_optimize), m_context(_compilerContext), m_currentLValue(m_context) {}
@@ -111,6 +114,9 @@ private:
 	/// Appends code for a State Variable accessor function
 	void appendStateVariableAccessor(VariableDeclaration const& _varDecl);
 
+	/// Appends code for a State Variable initialization
+	void appendStateVariableInitialization(VariableDeclaration const& _varDecl);
+
 	/**
 	 * Helper class to store and retrieve lvalues to and from various locations.
 	 * All types except STACK store a reference in a slot on the stack, STACK just
@@ -126,8 +132,13 @@ private:
 			   std::shared_ptr<Type const> const& _dataType, unsigned _baseStackOffset = 0);
 
 		/// Set type according to the declaration and retrieve the reference.
-		/// @a _expression is the current expression
+		/// @a _identifier is the current identifier
 		void fromIdentifier(Identifier const& _identifier, Declaration const& _declaration);
+
+		/// Set type according to the declaration and retrieve the reference.
+		/// @a _declaration is the variable declaration
+		void fromStateVariable(VariableDeclaration const& _declaration);
+
 		void reset() { m_type = LValueType::None; m_dataType.reset(); m_baseStackOffset = 0; m_size = 0; }
 
 		bool isValid() const { return m_type != LValueType::None; }
diff --git a/NameAndTypeResolver.cpp b/NameAndTypeResolver.cpp
index e19b0bf9e..15e1ac6f5 100644
--- a/NameAndTypeResolver.cpp
+++ b/NameAndTypeResolver.cpp
@@ -267,12 +267,12 @@ void DeclarationRegistrationHelper::endVisit(ModifierDefinition&)
 	closeCurrentScope();
 }
 
-void DeclarationRegistrationHelper::endVisit(VariableDefinition& _variableDefinition)
+void DeclarationRegistrationHelper::endVisit(VariableDeclarationStatement& _variableDeclarationStatement)
 {
 	// Register the local variables with the function
 	// This does not fit here perfectly, but it saves us another AST visit.
-	solAssert(m_currentFunction, "Variable definition without function.");
-	m_currentFunction->addLocalVariable(_variableDefinition.getDeclaration());
+	solAssert(m_currentFunction, "Variable declaration without function.");
+	m_currentFunction->addLocalVariable(_variableDeclarationStatement.getDeclaration());
 }
 
 bool DeclarationRegistrationHelper::visit(VariableDeclaration& _declaration)
diff --git a/NameAndTypeResolver.h b/NameAndTypeResolver.h
index d9ac98ce5..63b8ab637 100644
--- a/NameAndTypeResolver.h
+++ b/NameAndTypeResolver.h
@@ -105,7 +105,7 @@ private:
 	void endVisit(FunctionDefinition& _function) override;
 	bool visit(ModifierDefinition& _modifier) override;
 	void endVisit(ModifierDefinition& _modifier) override;
-	void endVisit(VariableDefinition& _variableDefinition) override;
+	void endVisit(VariableDeclarationStatement& _variableDeclarationStatement) override;
 	bool visit(VariableDeclaration& _declaration) override;
 	bool visit(EventDefinition& _event) override;
 	void endVisit(EventDefinition& _event) override;
diff --git a/Parser.cpp b/Parser.cpp
index 72334c6cc..9940fb8d9 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -148,6 +148,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
 		{
 			VarDeclParserOptions options;
 			options.isStateVariable = true;
+			options.allowInitialValue = true;
 			stateVariables.push_back(parseVariableDeclaration(options));
 			expectToken(Token::Semicolon);
 		}
@@ -324,9 +325,19 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(VarDeclParserOp
 	}
 	else
 		identifier = expectIdentifierToken();
-	return nodeFactory.createNode<VariableDeclaration>(type, identifier,
-												   visibility, _options.isStateVariable,
-												   isIndexed);
+	ASTPointer<Expression> value;
+	if (_options.allowInitialValue)
+	{
+		if (m_scanner->getCurrentToken() == Token::Assign)
+		{
+			m_scanner->next();
+			value = parseExpression();
+			nodeFactory.setEndPositionFromNode(value);
+		}
+	}
+	return nodeFactory.createNode<VariableDeclaration>(type, identifier, value,
+									visibility, _options.isStateVariable,
+									isIndexed);
 }
 
 ASTPointer<ModifierDefinition> Parser::parseModifierDefinition()
@@ -519,7 +530,7 @@ ASTPointer<Statement> Parser::parseStatement()
 		}
 	// fall-through
 	default:
-		statement = parseVarDefOrExprStmt();
+		statement = parseVarDeclOrExprStmt();
 	}
 	expectToken(Token::Semicolon);
 	return statement;
@@ -568,7 +579,7 @@ ASTPointer<ForStatement> Parser::parseForStatement()
 
 	// LTODO: Maybe here have some predicate like peekExpression() instead of checking for semicolon and RParen?
 	if (m_scanner->getCurrentToken() != Token::Semicolon)
-		initExpression = parseVarDefOrExprStmt();
+		initExpression = parseVarDeclOrExprStmt();
 	expectToken(Token::Semicolon);
 
 	if (m_scanner->getCurrentToken() != Token::Semicolon)
@@ -587,30 +598,22 @@ ASTPointer<ForStatement> Parser::parseForStatement()
 												body);
 }
 
-ASTPointer<Statement> Parser::parseVarDefOrExprStmt()
+ASTPointer<Statement> Parser::parseVarDeclOrExprStmt()
 {
-	if (peekVariableDefinition())
-		return parseVariableDefinition();
+	if (peekVariableDeclarationStatement())
+		return parseVariableDeclarationStatement();
 	else
 		return parseExpressionStatement();
 }
 
-ASTPointer<VariableDefinition> Parser::parseVariableDefinition()
+ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStatement()
 {
 	ASTNodeFactory nodeFactory(*this);
 	VarDeclParserOptions options;
 	options.allowVar = true;
+	options.allowInitialValue = true;
 	ASTPointer<VariableDeclaration> variable = parseVariableDeclaration(options);
-	ASTPointer<Expression> value;
-	if (m_scanner->getCurrentToken() == Token::Assign)
-	{
-		m_scanner->next();
-		value = parseExpression();
-		nodeFactory.setEndPositionFromNode(value);
-	}
-	else
-		nodeFactory.setEndPositionFromNode(variable);
-	return nodeFactory.createNode<VariableDefinition>(variable, value);
+	return nodeFactory.createNode<VariableDeclarationStatement>(variable);
 }
 
 ASTPointer<ExpressionStatement> Parser::parseExpressionStatement()
@@ -822,11 +825,11 @@ pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::pars
 }
 
 
-bool Parser::peekVariableDefinition()
+bool Parser::peekVariableDeclarationStatement()
 {
-	// distinguish between variable definition (and potentially assignment) and expression statement
+	// distinguish between variable declaration (and potentially assignment) and expression statement
 	// (which include assignments to other expressions and pre-declared variables)
-	// We have a variable definition if we get a keyword that specifies a type name, or
+	// We have a variable declaration if we get a keyword that specifies a type name, or
 	// in the case of a user-defined type, we have two identifiers following each other.
 	return (m_scanner->getCurrentToken() == Token::Mapping ||
 			m_scanner->getCurrentToken() == Token::Var ||
diff --git a/Parser.h b/Parser.h
index 1bb4ea977..4034aec85 100644
--- a/Parser.h
+++ b/Parser.h
@@ -51,6 +51,7 @@ private:
 		bool isStateVariable = false;
 		bool allowIndexed = false;
 		bool allowEmptyName = false;
+		bool allowInitialValue = false;
 	};
 
 	///@{
@@ -76,8 +77,8 @@ private:
 	ASTPointer<IfStatement> parseIfStatement();
 	ASTPointer<WhileStatement> parseWhileStatement();
 	ASTPointer<ForStatement> parseForStatement();
-	ASTPointer<Statement> parseVarDefOrExprStmt();
-	ASTPointer<VariableDefinition> parseVariableDefinition();
+	ASTPointer<Statement> parseVarDeclOrExprStmt();
+	ASTPointer<VariableDeclarationStatement> parseVariableDeclarationStatement();
 	ASTPointer<ExpressionStatement> parseExpressionStatement();
 	ASTPointer<Expression> parseExpression();
 	ASTPointer<Expression> parseBinaryExpression(int _minPrecedence = 4);
@@ -91,8 +92,8 @@ private:
 	///@{
 	///@name Helper functions
 
-	/// Peeks ahead in the scanner to determine if a variable definition is going to follow
-	bool peekVariableDefinition();
+	/// Peeks ahead in the scanner to determine if a variable declaration statement is going to follow
+	bool peekVariableDeclarationStatement();
 
 	/// If current token value is not _value, throw exception otherwise advance token.
 	void expectToken(Token::Value _value);
diff --git a/Types.cpp b/Types.cpp
index a9c480176..55dedd921 100644
--- a/Types.cpp
+++ b/Types.cpp
@@ -653,7 +653,7 @@ MemberList const& StructType::getMembers() const
 	// We need to lazy-initialize it because of recursive references.
 	if (!m_members)
 	{
-		vector<pair<string, TypePointer>> members;
+		MemberList::MemberMap members;
 		for (ASTPointer<VariableDeclaration> const& variable: m_struct.getMembers())
 			members.push_back(make_pair(variable->getName(), variable->getType()));
 		m_members.reset(new MemberList(members));