1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【C++】volatileと最適化の影響の確認

Posted at

C++でグローバル変数にvolatileの指定があったので「指定する意味あるの?」と思い、その効果を体験した。
環境: Ubuntu 22.04.2 LTS, g++ 11.3.0

ソースコード

グローバル変数を参照する無限ループを作成。
グローバル変数はシグナルハンドラで更新される。

main.cpp
#include <iostream>
#include <signal.h>

//volatile int a = 0; // volatile指定あり
int a = 0;            // volatile指定なし

void sig_handler(int signo) // シグナルハンドラ
{
	std::cout << "received signal: " << signo << "\n";
	a = 1;
}

int main()
{
	signal(SIGUSR1, sig_handler); // SIGUSR1受信時sig_handlerを実行
	while(a == 0)
	{
		// 無限ループ
	}
	std::cout << "got out from the loop\n";
}

コンパイル

端末01
$ g++ main.cpp

実行

端末01
$ ./a.out

別のターミナルからシグナル送信

端末02
$ killall -SIGUSR1 a.out

whileループを抜けてプログラムは終了

端末01
received signal: 10
got out from the loop
$

ここまでは期待通りの動作。

最適化付きコンパイル

コンパイル時に最適化を行う。
最適化の引数は複数存在する。今回は-O1 (基本的な最適化)と-O2(ほとんどの最適化)で試す。

-O1 (基本的な最適化)でコンパイルした結果

コンパイル

端末01
$ g++ main.cpp -O1

実行

端末01
$ ./a.out

別のターミナルからシグナル送信。何度か送信。

端末02
$ killall -SIGUSR1 a.out
$ killall -SIGUSR1 a.out
$ killall -SIGUSR1 a.out

シグナルハンドラは呼ばれているが、whileループは抜けずにプログラムは終了しない。

端末01
received signal: 10
received signal: 10
received signal: 10

マジか

-O2 (ほとんどの最適化)でコンパイルした結果

コンパイル

端末01
$ g++ main.cpp -O2

実行

端末01
$ ./a.out
got out from the loop

いきなりwhileループ抜けて勝手に終了。
何じゃそりゃ。

volatileの効果の確認

最適化で散々になった結果をvolatile指定で正常になることを確認。

コードの修正: volatile付きのグローバル変数を有効化

volatile int a = 0; // volatile指定あり
//int a = 0;            // volatile指定なし

コンパイル:-O1付き

端末01
$ g++ main.cpp -O1

実行

端末01
$ ./a.out

別のターミナルからシグナル送信

端末02
$ killall -SIGUSR1 a.out

whileループを抜けてプログラムは終了

端末01
received signal: 10
got out from the loop
$

期待通りの動作。

コンパイル:-O2付き

端末01
$ g++ main.cpp -O2

実行

端末01
$ ./a.out

別のターミナルからシグナル送信

端末02
$ killall -SIGUSR1 a.out

whileループを抜けてプログラムは終了

端末01
received signal: 10
got out from the loop
$

期待通りの動作。

結論

  • 最適化でプログラムは期待しない動作となった。
  • volatile指定で最適化で発生した問題が解消された。volatileを指定する意味があることがわかった。

めでたしめでたし

1
1
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?