yohhoyの日記

技術的メモをしていきたい日記

restrictキーワードへの対応状況

C99で導入された restrict キーワード(→id:yohhoy:20120223)への対応状況メモ。

gcc

gccはC99の restrict キーワードに対応している。また、C++でも利用可能な独自の __restrict__, __restrict キーワードを提供しており*1C/C++のポインタ型と参照型およびメンバ関数に対して利用可能。

VisualC++系

Visual Studio 2005(MSVC8)以降では直接restrictキーワードをサポートしないが、独自の __restrict キーワードが存在し、C/C++のポインタ型変数に対してのみ利用可能(参照型はNG)。

また独自拡張の__declspec(restrict)も存在するが、こちらは関数に対してのみ利用可能で、関数の戻り値に対してaliasが存在しない事を示す。

なお、一見関連する名前の __declspec(noalias) は関数修飾に用いられ、その関数が引数にのみ依存する純粋関数であることを表す。gcc__attribute__((pure)) に似ている*2

おまけVisual Studio .NET 2003(MSVC7.1)以前は「volatile修飾されていない全ての変数についてaliasが存在しないとみなし最適化を行う」という過激なコンパイラオプションが存在していた。なお、同オプションはMSVC8にて削除されている。

メモMSDNの "will not propagate the no-alias property" の意味を理解できていない。C99のrestrictでは伝搬するの?

When __restrict is used, the compiler will not propagate the no-alias property of a variable. That is, if you assign a __restrict variable to a non-__restrict variable, the compiler will not imply that the non-__restrict variable is not aliased. This is different from the behavior of the restrict keyword from the C99 specification.

http://msdn.microsoft.com/ja-jp/library/5ft82fed.aspx

2012-02-27追記:http://gcc.gnu.org/ml/gcc-help/2010-10/msg00151.htmlでふれているhttp://www.lysator.liu.se/c/restrict.html#assignments-to-unrestrictedあたりに関連する記述がある。いずれにせよ最適化のヒントでしかないし、C99規格で「非restrict修飾へ代入してもno-aliasな属性が伝搬する」とは要求しない気がする。

関連URL:

*1:C++では restrict が予約語となっていないための措置。

*2:厳密にはMSVCの __declspec(noalias) は「引数とポインタ型引数が直接指す先にのみに依存&更新」を行う準純粋関数であるのに対し、gccの __attribute__((pure)) は「戻り値が引数とグローバル変数にのみ依存」する純粋関数となる。