C++03とC++11の違いシリーズもそろそろ終わりが近づいていきた。今回は数値ライブラリー編だ。といっても、中身はひとつ、std::complexについてだ。
変更:std::complex<T>の特殊化の表現方法が規定された
C++03では、std::complexのメモリレイアウト、すわなち、オブジェクトがストレージ上でどのように表現されているかは、規定されていなかった。C++11では、C99の複素数ライブラリーと整合性をとるために、C++における複素数ライブラリーであるstd::complexの表現方法を厳格に規定した。
これにより、実装依存のメモリレイアウトに依存しているC++03のコードは、C++11では動かなくなるおそれがある。もっとも、そのようなコードは、もともと規格が動作を保証しないコードなので、自業自得だとも言える。
さて、std::complex<:T>:の表現方法はどのように規定されたのか。それは§26.4に書いてある。簡単にまとめると以下のようになる。
今、zがlvalue式で、その型がcv std::complex<T>であり、Tがfloat, double, long doubleのいずれかであるとすると、
- 式、reinterpret_cast<cv T(&)[2]>(z)は、正しく動く
- 式、reinterpret_cast<cv T(&)[2]>(z)[0]は、zの実数部を意味する
- 式、reinterpret_cast<cv T(&)[2]>(z)[1]は、zの虚数部を意味する
さらに今、cv std::complex<T> *型の式aがあったとして、a[i]は、妥当であるとすると、
- reinterpret_cast<cv T*>(a)[2*i]は、a[i]の実数部を意味する
- reinterpret_cast<cv T*>(a)[2*i + 1]は、a[i]の虚数部を意味する
まあ、かなりCの構造体(構造体のアドレスは実数部のアドレスと等しく、実数部と虚数部の間にパディングなし)に近いようなレイアウトになるわけだ。もちろん、C言語でもこの手の詳細は未規定なのだが。
あるいは、コードで書いたほうがわかりやすいかもしれない。もちろん、このような規定を正確に記述できる機能は標準C++にはないが、例えば以下のようなコードが、よくある環境では上のような意味になるかもしれない。
// 実装依存の例示用コード
template < typename T >
struct complex ;
template < >
struct complex<float>
{
float real ;
float imarginary ;
} ;
このような表現の詳細に頼ったコードは書きたくないものだが・・・、必要になるのかも知れぬ。
No comments:
Post a Comment
You can use some HTML elements, such as <b>, <i>, <a>, also, some characters need to be entity referenced such as <, > and & Your comment may need to be confirmed by blog author. Your comment will be published under GFDL 1.3 or later license with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.