<malloc.h>と<stdlib.h>の違いについてはすでに説明している人もいます。
どちらも含まれていない場合の警告は、C関数のしくみの定義です。プロトタイプのない関数(独自に宣言せず、ヘッダーを含まない場合にある関数)は、int
戻り型と未指定の引数リストを持つ関数として扱われます。
コンパイラーはデフォルトの昇格(例えば、float to doubleなど)を実行し、関数が呼び出されます。関数で使用される引数の数が渡された数と異なる場合、またはデフォルトの昇格後の引数のタイプが関数の実装と互換性がない場合、それは未定義の動作です。
ISO 9899:1999(C99)§6.5.2.2、¶6を参照してください:
呼び出された関数を表す式の型がプロトタイプを含まない場合、整数の昇格が各引数で実行され、型のある引数float
がに昇格されdouble
ます。これらはデフォルトの引数プロモーションと呼ばれます。引数の数がパラメーターの数と等しくない場合、動作は定義されていません。関数がプロトタイプを含む型で定義されていて、プロトタイプが省略記号(、...)で終わっているか、昇格後の引数の型がパラメーターの型と互換性がない場合、動作は未定義です。関数がプロトタイプを含まない型で定義されており、昇格後の引数の型が昇格後のパラメーターの型と互換性がない場合、次の場合を除いて、動作は未定義です。
- 1つのプロモート型は符号付き整数型であり、もう1つのプロモート型は対応する符号なし整数型であり、値は両方の型で表現可能です。
- どちらのタイプも、文字タイプまたはの修飾バージョンまたは非修飾バージョンへのポインター
void
です。
プロトタイプなしで呼び出す場合malloc()
、これは非常に悪い可能性があります。 引数をmalloc()
受け入れ、ポインタを返します。整数引数のデフォルトの昇格の結果、サイズがとは異なる整数が生成される場合、未定義の動作が発生します。また、がと異なるサイズの場合(たとえば、64ビットシステムでは、多くの場合32ビットで64ビットになります)、返されるポインタは混乱します。size_t
void *
size_t
int
void *
int
void *