The fact that the code in the bodies of the loops are quite different means that "better" can't meaningfully be applied. There are situations where the C style loop is "better", but in the general case the Perl style for loop is "better".

The C style for loop for (initialisation; condition; expression) {...} is equivalent to:

where the three parts (initialisation, condition and expression) need not be related to each other in any way except they are all part of the same for loop header. That allows the C for loop to be abused in many ways. The clutter in the loop header often makes it difficult to see the various parts and the nature of the condition means that C style for loops are very prone to off by one errors.

The Perl for loop on the other hand is simple. All it does is iterate over a list of elements. The list may be the contents of an array, or the members of a list generated using the range operator or something tricky using map, grep or whatever, but always the Perl for loop simply iterates over a list. (Internally the for loop code may employ various tricks to improve memory usage or speed, but those are unimportant to our current discussion.)

It is worth remembering that the Perl for loop can be used as a statement modifier so your loop could be:

But the OP wants to conform to the styleguides of PBP & Perl Critics, and postfix-loops are disadviced

PBP advises against a lot of useful things. That doesn't mean that you shouldn't use them. It means that you shouldn't use them without a little bit of thought. In the right place, a C-style for loop is Just Fine. In the right place, a "postfix-loop" is Just Fine.

but that would be a particularly bad way to do it. A C for loop is generally a poorer solution that a Perl for loop because there are more parts to go wrong. A C style for loop is highly suceptible to off by one errors.

I personally believe I may come out as an annoying little voice, but I have to join the chorus: that is a statement-modifier-for which happens to have the form of Perl-style C<for> acting on $_ - and saving you the need of parens. But by a (generic) Perl-style C<for> it is meant either:

"C-style" is in no way bad "because of useless $i variable" since indeed there may not be any $i variable at all: it's "just" a completely different kind of loop altoghether (a more generic one - and that is fundamentally the reason why it exists at all,) which bears the same name as Perl-style one due to the fact that it can easily be disambiguated from the latter by means of the syntax of what's in the parens. I would go as far as claiming that what's in the parens itself in that case is yet another minilanguage (very closely related to Perl itself: it consists of exactly three Perl statements!) that does not fit in other parts of Perl's syntax, and thus a very special case: of course Perl 6 knows better and gives it an entirely different name which IIRC is C<loop> and not by chance takes one letter more wrt "for" since that's for huffmanization and in fact it is thought to be on a much sparser basis to begin with.

I would go as far as claiming that what's in the parens itself in that case is yet another minilanguage (very closely related to Perl itself: it consists of exactly three Perl statements!) that does not fit in other parts of Perl's syntax, and thus a very special case: of course Perl 6 knows better and gives it an entirely different name which IIRC is C<loop> and not by chance takes one letter more wrt "for" since that's for huffmanization and in fact it is thought to be on a much sparser basis to begin with.

A couple of points.

I won't deny Perl 6 gives it a different name, but the Perl 5 parser already knows the 'loop' construct. perly.y has a token 'loop' under which all loop, including the bare block and 4 (!) 'for' constructs. (for my $v (), for $v (), for (), are all parsed separately).

The C-style for loop doesn't have three statements inside the parens, it has three expressions - each of which may be empty.

Each of the expressions is a different kind of expression (first introduces a scope, second is a boolean expression, third may introduce a scope), but they do fit in other parts of Perls syntax. Of course, you are right in the sense that 'for (;;)' is the only place that requires exactly three expressions.

I don't understand the huffmanization remark. Huffmanization means you're minimizing the length of the average program, using tokens that are never a prefix of another token. Making little used tokens longer makes sense, but only if you either the freed up token for something that's used more often, or if the freed token is a prefix of some other token that cannot be replaced. So, what keyword starting with 'for' is used in Perl6? Surely you aren't saying in Perl6 'format' is going to be used more often than 'loop'? ;-)

So everything that is part of Perl is undiluted goodness? How about the two parameter open or the .. operator that is two completely different an unrelated operators depending on context (where the context can be very subtle at times)?

Perl's for loop is much closer to "intuitive" than C's for loops. Sure, C's for loops are comfortable for a C programmer, but that doesn't make them intuitive, predictable or easy compared with Perl's loops.

Perl is a different language than C. Just because you can write C (or FORTRAN for that matter) in Perl doesn't mean you should. Embrace the Perly goodness and cast off the C baggage - use Perl for loops unless you really, really, really absolutely can't avoid using a C style loop.