I missed this when it came out, and my addition is too long to comment, so I'll add another answer here just to share what the documentation on SOQL For Loops recommends (emphasis mine):
###SOQL For Loops Versus Standard SOQL Queries
SOQL For Loops Versus Standard SOQL Queries
SOQL for loops differ from standard SOQL statements because of the method they use to retrieve sObjects. While the standard queries discussed in SOQL and SOSL Queries can retrieve either the count of a query or a number of object records, SOQL for loops retrieve all sObjects, using efficient chunking with calls to the query and queryMore methods of the SOAP API. Developers should always use a SOQL for loop to process query results that return many records, to avoid the limit on heap size.
Note that queries including an aggregate function don't support queryMore. A run-time exception occurs if you use a query containing an aggregate function that returns more than 2,000 rows in a for loop.