From the JSTL specs I can read this
<c:forEach>
Repeats its nested body content over a collection of objects, or repeats it a fixed
number of times.
... what I understand is:
to iterate with c:forEach you need to provide either <items> or <begin> && <end> otherwise you can not iterate, that's why <items> && <begin> && <end> are not mandatory because you are allowed to skip one (items) or the other (begin && end), depending on what you are iterating over.
If you skip <items> you have to provide <start> && <end>.
If you have <items> you can skip <end> or both <start> && <end>
For the other attributes I guess it's easier to understand why they are not mandatory.