C言語やC++の入門書を読めば、プログラムはmain関数から始まると書かれています。そのこと自体は間違っていませんが、「必ず」そうかというと3つの意味で正しくありません。ひとつはスタートアップの存在であり、ひとつはフリースタンディング環境の場合であり、もうひとつはC++における非局所オブジェクトの動的初期化です。
スタートアップ
知っている人から見れば屁理屈のように思うかもしれませんが、知らない人も少なくないと思いますので、あえてとり上げることにします。main関数が呼び出される前にはスタートアップという処理が実行されます。スタートアップでは、少なくともmain 関数に渡す引数を組み立て、標準入力・標準出力・標準エラーの三つのストリームをオープンし、そしてmain関数を呼び出します。main関数から帰った後は、exit関数と同等の処理を行います。
フリースタンディング環境
フリースタンディング環境は、OSに依存しない実行環境のことです。組込みプログラムなどはフリースタンディング環境で動作することが多いといえます(組込みでもLinuxなどのOSを搭載することは少なくないので、組込みだからフリースタンディング環境ということにはなりません。いわゆる「ベアメタル」な環境がこれに当たります)。
フリースタンディング環境では、プログラムの最初に呼び出される関数はmainとは限りません。最初に呼び出される関数がどんな名前でどんな型を持つかは処理系定義です。
動的初期化
C++では、非局所オブジェクト、すなわち関数の外で定義したオブジェクトが定数式以外の初期化子を持つ場合や、コンストラクタを持つ場合には、動的に初期化が行われます。この初期化はmain関数が呼び出される前に実行されます。例えば、初期化子で関数呼び出しを行うことができますし、コンストラクタは一種の関数ですから、main関数より前にユーザープログラムが実行されていることになります。