Ubuntu18では正常に動いていたアプリケーションがあったのですが、OSのバージョンアップが必要になったため、Ubuntu20の環境でビルド・動作確認を実施。
すると、今までパスしていたテストが通らなくなってしまったので、色々と調査したところ、コンテナのサイズに関係なく、Qtのforeach文が1回分しかループを回していないという事実が判明しました。
Qtのforeach文はマクロ定義されていて、C++11以降で使えるようになった拡張for文とほぼ同じような感覚で使えます。
QList<qint32> qList;
qList << 1;
qList << 2;
qList << 3;
qList << 4;
foreach (qint32 val, qList)
{
std::cout << val;
}
通常であれは「1234」の出力が期待できますが、「1」しか出力されないというのが今回起きた事象です。
調べてみたところ、どうやら同じ事象がstack overflowで話題に上がっているようでした。
https://stackoverflow.com/questions/61635549/qt-foreach-only-iterates-once-ignoring-the-rest-of-the-items
バグレポートとしても上がっているようです。
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90617
どうやらfor文の増減式の部分にbreakを入れた場合の振る舞いが、gcc9とそれより前のバージョンで異なることで、この問題が発生しているようです。
どちらかというと、gcc9より前では間違った動きをしていたので、gcc9ではそれが修正されているということのようですね。
Qt5ではこれを受けてかforeachのマクロ定義が異なった処理に修正されていますので、gcc9でコンパイルしても問題ないようです。
いずれにせよ、Qt4とgcc9の組み合わせで使用せざるを得ない場合は、foreach文の使用を避けて、通常のfor文や拡張for文を使うか、イテレーターを使ってコンテナに対してのループを回す必要があるということですね。