3

このコードがコンパイルされる理由が少しわかりません。「必要」#include <OpenGL/gl.h>を省略しても、プログラムはコンパイルできます。私のプログラムがGLライブラリから関数を呼び出しているときに、それらを含めずにこれがどのように可能になるのですか?

int main(int argc, char** argv)
{

    glClearColor(1.0,1.0,1.0,1.0);
    return 0;
}

私はこのコンパイルコマンドを使用します:

 gcc -framework GLUT -framework OpenGL test.c

-framework を追加すると、ライブラリの場所をリンカに指定するだけであると想定していましたが、それでもヘッダーが必要だと思いましたか?

4

3 に答える 3

5

glClearColor はマクロではないため、ヘッダーで定義する必要はありません。警告を追加する場合:

gcc -o test -Wall -W test.c -framework GLUT -framework OpenGL

次に、glClearColor の暗黙の宣言に関する警告が表示されます。また、マクロが定義されていないというエラーがコンパイラによって表示されるため、マクロを使用することもできません。glClearColor シンボルはリンカーによって適切に解決されるため、エラーが発生することはありません。

また、C++ 用にコンパイルしていると思っていたので、これについて不思議に思っていたかもしれません。あなたが示した例は、関数プロトタイプの宣言に失敗してもエラーにならない C コードを実際にコンパイルします。これを C++ コードとしてコンパイルする場合は、次のコマンド ラインが必要になります。

g++ -o test test.cpp -framework OpenGL

その場合、gl.h をインクルードしないというエラーが発生し、コードのコンパイルに失敗することは間違いありません。コマンド ラインから GCC を実行する場合、g++ は C++ コンパイラであり、gcc は一般的な C コンパイラです。

于 2008-11-10T06:48:49.773 に答える
3

C (C99 より前) では、関数を使用するために関数を宣言する必要はありません。コンパイラは、関数が渡された昇格されたパラメーターの型を受け取ると想定し、関数が を返すと想定しますint。ただし、これは非常に問題になる可能性があり、関数が定義されていない場合の動作は未定義です。これを見てみましょう:

/* file1.c */
void foo(char a, char b) {
    /* doing something ... */
}

/* main.c */
int main(void) {
    char a = 'a', b = 'b';
    /* char variables are promoted to int 
       before being passed */
    foo(b, a); 
}

呼び出し時に関数の宣言がない場合、型がプロモート ( char -> int, float -> double) されるため、メモリ内の適切な場所で引数を渡すことができなくなります。b にアクセスすると、パラメーターの興味深い値が得られる可能性があります。vararg functionsサイド ノードとして、 like prinft、またはプロトタイプを持たない関数 (void f()パラメーターの型とカウントに関する情報がないなど) に引数を渡すと、同じ問題が発生します。va_argこれが、昇格された型を使用して常に可変引数にアクセスする必要がある理由です。そうしないと、GCC から警告が表示されます。

この問題に遭遇しないように、常に適切なヘッダー ファイルを含めてください。

編集:char literals (like 'a') は常にintC の型であることを指摘してくれた Chris に感謝します

于 2008-11-10T06:53:29.513 に答える
0

これは実際には、古典的な C&R の hello world スニペットに関連しています:
http://en.wikipedia.org/wiki/Hello_world#History

于 2008-11-10T08:28:58.090 に答える