13

C99 標準のセクション 7.18.1.1パラグラフ1:

typedef 名は、幅N、パディング ビットなし、および 2 の補数表現をintN_t持つ符号付き整数型を指定します。

C99 標準によると、正確な幅の符号付き整数型は2 の補数表現を持つ必要があります。これは、たとえば、1 の補数の最小値ではなくint8_t、 の最小値を持つことを意味します。-128-127

セクション 6.2.6.2パラグラフ 2 では、実装で符号ビットを符号と大きさ2 の補数、または1 の補数として解釈するかどうかを決定できます。

符号ビットが 1 の場合、値は次のいずれかの方法で変更されます。
— 符号ビット 0 の対応する値は否定されます (符号と大きさ)。
— 符号ビットの値は -(2 N ) ( 2 の補数) です。
— 符号ビットの値は -(2 N - 1) ( 1 の補数) です。

2 の補数( ) の整数の最小値は、1 の補数( ~ )-128で表現可能な値の範囲外になる可能性があるため、メソッド間の違いは重要です。-127127

実装が型を表現を持つものとして定義し、型にはintC99標準で保証されている表現があるとします。ones' complementint16_ttwo's complement

int16_t foo = -32768;
int bar = foo;

この場合、 が保持する値が で表現できる値の範囲外であるため、 からint16_tへの変換intによって実装定義の動作が発生しますか?foobar

4

1 に答える 1

8

はい。

具体的には、変換によって実装定義の結果が得られます。( 以外の値の場合-32768、結果と動作は明確に定義されます。)または、変換により実装定義のシグナルが発生する可能性がありますが、それを行う実装は知りません。

変換規則の参照: N1570 6.3.1.3p3:

それ以外の場合、新しい型は署名され、値を表現できません。結果が実装定義であるか、実装定義のシグナルが発生します。

これは、次の場合にのみ発生します。

  • int16ビットです(より正確には、15個の値ビット、1個の符号ビット、および0個以上のパディングビットがあります)
  • int1 の補数または符号と大きさを使用する
  • 実装は 2 の補数もサポートします (それ以外の場合は を定義しませんint16_t)。

これらの基準を満たす実装を見て驚いています。2 の補数と 1 の補数または符号と大きさの両方をサポートする必要があり、後者のいずれかを type に選択する必要がありintます。(おそらく、非 2 の補数の実装は、ソフトウェアで 2 の補数をサポートする可能性があります。これは、 を定義できるようにするためint16_tです。)

この可能性が心配な場合は、ヘッダー ファイルの 1 つにこれを追加することを検討してください。

#include <limits.h>
#include <stdint.h>

#if !defined(INT16_MIN)
#error "int16_t is not defined"
#elif INT_MIN > INT16_MIN
#error "Sorry, I just can't cope with this weird implementation"
#endif

s は、#error現実世界の正常な実装でトリガーされる可能性はほとんどありません。

于 2013-08-07T19:46:24.090 に答える