13

Cの「標準」符号付き整数型(short、int、longなど)に対するすべての操作は、[TYPE_MIN、TYPE_MAX]間隔(TYPE_MIN、TYPE_MAXが最小および最大整数値)外の結果を生成する場合、未定義の動作を示します。それぞれ、特定の整数型で格納できます。

ただし、C99標準によれば、すべてのintN_tタイプは2の補数表現を持つ必要があります。

7.8.11.1正確な幅
の整数型1.typedef名intN_tは、幅N、パディングビットなし、2の補数表現の符号付き整数型を指定します。したがって、int8_tは、正確に8ビットの幅を持つ符号付き整数型を示します。

intN_tこれは、整数のオーバーフローの場合にC99の型が明確に定義された動作を示すことを意味しますか?たとえば、このコードは明確に定義されていますか?

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(void)
{
    printf("Minimum 32-bit representable number: %" PRId32 "\n", INT32_MAX + 1);
    return 0;
}
4

2 に答える 2

13

いいえ、そうではありません。

タイプの範囲内の値の2の補数表現の要件は、オーバーフロー時の動作について何も意味しません。

の型は<stdint.h>、既存の型の単なるtypedef(エイリアス)です。typedefを追加しても、型の動作は変わりません。

C標準(C99とC11の両方)のセクション6.5パラグラフ5は引き続き適用されます。

式の評価中に例外的な条件が発生した場合(つまり、結果が数学的に定義されていないか、その型の表現可能な値の範囲内にない場合)、動作は未定義です。

符号なし操作はオーバーフローしないため、これは符号なし型には影響しません。これらは、ラップされた結果を生成するように定義されており、モジュロTYPE _MAX + 1が削減されます。ただし、符号なしタイプintは(符号付き)にプロモートされるよりも狭いintため、同じ問題が発生する可能性があります。たとえば、これは次のとおりです。

unsigned short x = USHRT_MAX;
unsigned short y = USHRT_MAX;
unsigned short z = x * y;

shortが。より狭い場合、未定義の動作を引き起こしintます。(shortintがそれぞれ16ビットと32ビットの場合、はを65535 * 65535生成します。4294836225これはを超えINT_MAXます。)

于 2012-02-20T19:29:56.013 に答える
4

範囲外の値をメモリに格納されている符号付き型に格納すると、通常、値の下位ビットが格納され、メモリから値を再ロードすると符号拡張されますが、多くのコンパイラの最適化では、符号付き演算はそうで​​はないと想定する場合があります。オーバーフロー、およびオーバーフローの影響は、多くの実際のシナリオでは予測できない場合があります。簡単な例として、戻り値に1つの32ビットアキュムレータを使用する16ビットDSP(TMS3205Xなど)ではint16_t foo(int16_t bar) { return bar+1;}、コンパイラはアキュムレータに自由にロードbar、符号拡張、追加して、 。呼び出し元のコードがたとえばの場合、コードは-32768ではなく32768long z = foo(32767)に設定されている可能性があります。z

于 2013-05-11T00:11:35.420 に答える