177

自分で作成したライブラリがあり、

ファイルmylib.c:

#include <mylib.h>

int
testlib() {
    printf("Hello, World!\n");
    return (0);
}

ファイルmylib.h:

#include <stdio.h>
extern int testlib();

私のプログラムでは、このライブラリ関数を呼び出そうとしました:

ファイルmyprogram.c :

#include <mylib.h>

int
main (int argc, char *argv[]) {
    testlib();
    return (0);
}

このプログラムをコンパイルしようとすると、次のエラーが発生します。

myprogram.c:1 からインクルードされたファイル
mylib.h:2 警告: 関数宣言はプロトタイプではありません

私は使用しています:gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)

関数プロトタイプを宣言する適切な方法は何ですか?

4

3 に答える 3

376

C ではint foo()int foo(void)は異なる機能です。int foo()は任意の数の引数をint foo(void)受け入れますが、0 個の引数を受け入れます。C++ では、同じことを意味します。void引数がないことを意味する場合は、一貫して使用することをお勧めします。

a変数がある場合は、それが別の翻訳単位に存在する可能性のあるシンボルであるextern int a;ことをコンパイラに伝える方法ですa(C コンパイラはソース ファイルについて話します)。リンク時まで解決しないでください。一方、関数名であるシンボルは、とにかくリンク時に解決されます。関数のストレージ クラス指定子 ( extern, static) の意味は、その可視性にのみ影響しextern、デフォルトであるため、extern実際には不要です。

を削除することをお勧めしますextern。これは無関係であり、通常は省略されます。

于 2008-09-06T17:58:18.500 に答える
58

簡単な答え: に変更int testlib()int testlib(void)て、関数が引数を取らないことを指定します。

プロトタイプは、定義上、関数の引数の型を指定する関数宣言です。

のような非プロトタイプ関数宣言

int foo();

引数の数や型を指定しない古いスタイルの宣言です。(1989 ANSI C 標準より前では、これは言語で使用できる唯一の種類の関数宣言でした。) このような関数は任意の数の引数で呼び出すことができ、コンパイラは文句を言う必要はありません。呼び出しが定義と矛盾しています。プログラムには未定義の動作があります。

1 つ以上の引数を取る関数の場合、宣言で各引数の型を指定できます。

int bar(int x, double y);

引数のない関数は特殊なケースです。論理的には、空の括弧は、関数が引数を取らないことを指定する良い方法でしたが、その構文は古いスタイルの関数宣言に既に使用されていたため、ANSI C 委員会はvoidキーワードを使用して新しい構文を発明しました。

int foo(void); /* foo takes no arguments */

関数定義(関数が実際に行うことのコードを含む) も宣言を提供します。あなたの場合、次のようなものがあります。

int testlib()
{
    /* code that implements testlib */
}

これは、 の非プロトタイプ宣言を提供しますtestlib。定義として、これはtestlibパラメーターを持たないことをコンパイラーに伝えますが、宣言としては、testlib指定されていないが固定された数と型の引数を取ることのみをコンパイラーに伝えます。

宣言に変更()する(void)とプロトタイプになります。

プロトタイプの利点は、誤っtestlibて 1 つ以上の引数を呼び出した場合に、コンパイラがエラーを診断することです。

(C++ には少し異なるルールがあります。C++ には古いスタイルの関数宣言がありません。空の括弧は、関数が引数を取らないことを明確に意味します。C++ は、C(void)との一貫性のために構文をサポートしています。 C および as C++ の場合、おそらく()C++ では を、C では(void)構文を使用する必要があります。)

于 2013-12-30T16:49:20.700 に答える
24

試す:

extern int testlib(void);
于 2008-09-03T17:11:31.527 に答える