Если бы так все просто было. Вывод в stderr небуферизирован и выводится сразу, как только увиден '\n', а в stdout, если в файл, то по достижению буфера. Немного экспериментов показали, что, по крайней мере bash скрипты соблюдают порядок, но при любой компиляции, при вашей комбинации - сравнив вывод с файла и терминала, увидете, что все сообщения об ошибках идут на терминал более менее по порядку (поскольку вывод на терминал буферизирован в ядре построчно), а в файле - сначала все то, что в stderr, a потом в stdout, периодами (поскольку тут буферизация поблочно).
Выполните - на любой программе в исходниках, warn всяко будут при компиляции программы нормального размера - make 2>&1 | tee FILE и сравните вывод на терминал - увеличив буфер до бесконечности и "FILE"