すべてのC関数にはプロトタイプが必要です。これらは実際には必須ではありませんが、使用しない理由はありません(これらをサポートしていないANSI以前のコンパイラを使用している場合を除きます)。(ただし、この回答の下部を参照してください。)
可変数の引数を取る関数が必要な場合、そのプロトタイプはで終わる必要が, ...
あり、関数自体は<stdarg.h>
その引数を処理するメカニズムを使用する必要があります。(これには、定義されたタイプの引数が少なくとも1つ必要です。その引数は、次の引数のアンカーとして使用されます。)ここおよび他の場所で文書化されています。
これを入力しているときに、質問を「注:ライブラリ((...)など)は使用しないでください」で更新しました。<stdarg.h>
は、自立型(埋め込み)のものを含む、すべての準拠C実装に必要な数少ないヘッダーの1つです。これは、関数を定義せず、型とマクロのみを定義するためです。C実装はそれをサポートする必要があります。そうでない場合は、準拠しているC実装ではないため、使用しているコンパイラを正確に通知するか、ドキュメントを読んで可変個引数関数または同等の機能を処理する方法を確認する必要があります。
, ...
と<stdarg.h>
、(またはおそらく古い)を実際に使用できない場合は<varargs.h>
、すべての使用に十分な固定数の引数を使用して関数を定義し、呼び出し元に追加のnullポインターを渡させることができます。
編集:
これは、コメントとチャットの新しい情報に基づく更新です。
printf
OPには、何らかの理由で表記または。を使用しない、一部のTIマイクロコントローラに実装する宿題があります。問題のコンパイラは明らかにC89/C90を実装しているため、両方の機能をサポートしています。これは任意の制限です。, ...
<stdarg.h>
この情報は問題になっているはずです。そのため、OPが更新するまで私はこの情報に反対票を投じています。
これを実現するための移植可能な方法はありません。これがまさに, ...
標準言語の<stdarg.h>
一部であり、標準ライブラリの一部である理由です。
おそらく最良のアプローチは、とを使用するプログラムを作成し, ...
、<stdarg.h>
コンパイラーを呼び出して、プリプロセッサーの出力のみを表示し(さまざまなva_*
マクロとva_list
タイプを解決)、それを模倣することです。また、可変個引数関数と非可変個引数関数の呼び出し規約に互換性があることを前提とするか、コンパイラのドキュメントを使用して確認する必要があります。言い換えれば、この特定の実装が何をするのかを調べ、同様のホイールを再発明します。
(宿題のポイントは、標準的なテクニックがどれだけ優れているかを示すことだと思います。)
更新2:
私は、すべてのC関数にプロトタイプが必要であることを上に書きました。これは、実際にはこのルールのまれな例外である可能性があります。これらの呼び出しの少なくとも1つ:
printf("Hello\n");
printf("x = %d\n", 42);
printf
で宣言されているか, ...
(宿題の割り当てで禁止されている)、またはの目に見えるプロトタイプがない場合を除いて、準拠するコンパイラから診断を生成する必要がありますprintf
。プロトタイプがない場合、少なくとも1つの呼び出しの動作が未定義になります(特定のコンパイラーによって定義されている場合でも、C標準で定義されていない動作)。
実際、宿題の要件を満たすには、ANSIC以前のコンパイラを使用しているふりをする必要があります。