By exactly the same reasoning, you should cast the return value of
malloc() since this is required for portability to C++.
The problem is that other things are required for portability to C++,
like for example avoiding the use of C++ keywords as identifiers.
Casting malloc is just fine.
In fact, it's useful in a C compiler to have C++-style type checking
for void *: that is to say, implicit conversions from void * to some
other pointer type being diagnosed.
If you have this warning and turn it on, it will generate false
positives in every place where you have not cast the return value of
malloc.
The rationale for /not/ casting malloc is outdated, based on the idea
that compilers allow functions to be called without a prior
declaration, without issuing a diagnostic.
Whether or not the code is to be portable to C++ has to be a project-
level decision. Either you decide to do it, and you do it correctly
and thoroughly, or you don't do it at all.
As a superior pedant, upon seeing interspersed declarations and
statements, I would raise the question: what is the project's policy
regarding the language dialect that is used?
If the project's policy dictates that the project is in C89, then the
usage is in violation of that policy.
Moreover, it's possible that the construct is only accepted because
the compiler is in fact operating in a non-conforming extension mode
superimposed over the C89 dialect. It could be the project's policy to
use that compiler's dialect, or it could be unintentional: namely that
nobody had the presence of mind to configure the compiler to standard-
conforming mode. That could be a problem, because in that case,
unintentional uses of extensions can creep in---including extensions
which are uncommon, or in fact not found in any other compiler.
Code reviewers have to look not only for bugs, but for adherence to
coding conventions (and be pedantic about that just as much as
language issues). They have to discover unclear and inconsistent
policies also.