2011-06-19 6 views
13

このプログラムをチェックしてくださいintが4バイトですが、まだ何のオーバーフロー

#include<stdio.h> 

int main(){ 

char c='a'; 
printf("%d %d", sizeof(c),sizeof('a')); 
} 

出力は、我々は声明チャーのC =「」を書くとき、私は知っている1 4
ありませんされている理由、それは、charに格納することができます;

その後、どのように何のオーバーフローがなど

+1

コンパイラはスマートです。 :) –

+3

奇妙なことに、 'sizeof( 'a')'はCとC++の違いの1つです(後者は前者の厳密なスーパーセットではありません):Cでは 'sizeof( 'a')== sizeof (int) '、C++では' sizeof( 'a')== sizeof(char)== 1'です。 –

答えて

15

まず、ANSI当たり/ IEC 9899:1999(E)§6.4.4.4:

  10の整数文字定数はint型を持ちます。 1バイトの実行文字にマップする1文字を含む整数文字定数 の値は、整数として解釈されるマップ文字の表現の 数値です。 [...]

§6.5.3.4:

  2. sizeof演算子は 発現または括弧名であってもよい、そのオペランドのサイズ(バイト単位)を、得られますタイプ。サイズは、オペランドの のタイプから決定されます。 [...]

  3をチャー、unsigned char型、またはsigned char型、 (またはその修飾バージョン)型を持つオペランドに適用した場合の結果が1である[...]

文字定数の型はintなので、sizeof('a')の場合はsizeof(int)となり、プラットフォームによっては4となります。しかし、sizeof(c)のために、我々は、なぜ我々はchar'a'を割り当てることができます。1.

になるように定義されchar、のサイズを取得しますか?

§6.5.16.1:単純代入(=)で

  2、右オペランドの値が代入式の型に変換によって指定されたオブジェクトに格納された値を置き換えています左のオペランド。

ので、'a'あるintは、暗黙的にcharに変換されます。 intを暗黙的にcharに変換できることを明示する例もあります。

+5

そして、もしあなたが*本当にペタンティックになりたいなら、6.3.1.3/1を "新しいタイプで値を表現できるならそれは変わらない"と6.2.5/3を "基本実行キャラクタセットのメンバを格納するのに十分なもの」、および5.2.1/3「基本実行キャラクタセットは...ラテンアルファベットの26の小文字を持つ」:-) –

1

が存在しない理由を1バイト(char型のC)のスペースに4バイト(ASCIIコード)のいくつかのことが格納されている(「文字リテラルはint型を持っている」ということが起こるんhttp://publib.boulder.ibm.com/infocenter/lnxpcomp/v7v91/index.jsp?topic=%2Fcom.ibm.vacpp7l.doc%2Flanguage%2Fref%2Fclrc02ccon.htm)

しかしCでは、理論的には「安全でない」自動キャスト - 例えば、

char c = 34; 

34が明らかに4バイトであってもt。これを安全にするのは、あなたが 'a'を書く時に、本当に1文字のアスキー文字なので1バイトであることを知っていることです。

途中でニースの質問 - ちょっと私を混乱させる。

2

コンパイラは暗黙的にintcharに変換します。最後の行は、コンパイラによって解釈され

int i = 42; 
char c = i * 2 - 4; 

char c = (char)(i * 2 - 4); 

これらimplicit type conversionsは、コンパイラによって処理されている - 何の「バッファオーバーフロー」はありません。 (char)は内部で処理されます(マシン自体によって、おそらくintのような単純なタイプの場合)。余分なバイトを適切に減らし、 "signedness"(+/-)を保存します。