I am a bit confused why this code compiles. I leave out the "necessary" #include <OpenGL/gl.h>
and still the program can compile. How is this possible when my program is calling functions from the GL library, without including them.
我有点困惑为什么这个代码编译。我省略了“必要的”#include
int main(int argc, char** argv)
{
glClearColor(1.0,1.0,1.0,1.0);
return 0;
}
I use this compilation command:
我使用这个编译命令:
gcc -framework GLUT -framework OpenGL test.c
I was under the assumption that adding -framework just specifies to the linker where the library is, but I thought I still need the headers?
我假设添加-framework只是指定了库所在的链接器,但我还以为我还需要头文件?
3 个解决方案
#1
3
In C (prior to C99), you don't have to declare functions in order to use them. The compiler will assume the function takes the promoted parameter types you pass to it, and assume the function returns an int
. This, however can be quite problematic, and behavior is undefined if the function doesn't. Let's look at this:
在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);
}
Because the types are being promoted (char -> int, float -> double
) if there is no declaration of the function at the time you call it, the arguments could not be passed at the right places in memory anymore. Accessing b can yield to a curious value of the parameter. As a side node, the same problem occurs when you pass arguments to vararg functions
like prinft
, or functions having no prototype (like void f()
, where there is no information about the parameters types and count). This is the reason that you always have to access variadic arguments with va_arg
using their promoted type. GCC will warn you if you don't.
因为正在提升类型(char - > int,float - > double),如果在调用它时没有函数声明,则参数不能再在内存中的正确位置传递。访问b可以产生参数的奇怪值。作为一个副节点,当您将参数传递给vararg函数(如prinft)或没有原型的函数(如void f(),其中没有关于参数类型和计数的信息时)会出现同样的问题。这就是您始终必须使用其提升类型使用va_arg访问可变参数的原因。如果你不这样做,GCC会警告你。
Always include the proper header files, so you don't run into this problems.
始终包含正确的头文件,因此您不会遇到此问题。
Edit: thanks to Chris for pointing out that char literals
(like 'a'
) are always of type int
in C
编辑:感谢Chris指出char文字(如'a')在C中始终是int类型
#2
5
glClearColor isn't a macro so you don't need the headers to define it. If you add warnings:
glClearColor不是宏,因此您不需要标头来定义它。如果添加警告:
gcc -o test -Wall -W test.c -framework GLUT -framework OpenGL
Then you'll get a warning about the implicit declaration of glClearColor. You also won't be able to use any macros as the compiler will give you an error that they are undefined. Since the glClearColor symbol gets properly resolved by the linker, you never get an error.
然后你会得到关于glClearColor的隐式声明的警告。您也将无法使用任何宏,因为编译器会给您一个未定义的错误。由于glClearColor符号由链接器正确解析,因此您永远不会收到错误。
It also occurs to me that you might have been wondering this because you thought you were compiling for C++. The example you gave actually compiles C code where it is not an error to fail to declare function prototypes. If you meant to compile this as C++ code, you would need the following command line:
我也想到你可能一直在想这个,因为你以为你在编译C ++。您提供的示例实际上编译了C代码,其中未能声明函数原型并不是错误。如果您打算将其编译为C ++代码,则需要以下命令行:
g++ -o test test.cpp -framework OpenGL
g ++ -o test test.cpp -framework OpenGL
In that case you most certainly would get an error for not including gl.h and your code would fail to compile. When executing GCC from the command line, g++ is the C++ compiler while gcc is the general C compiler.
在这种情况下,你肯定会因为不包括gl.h而出错,你的代码将无法编译。从命令行执行GCC时,g ++是C ++编译器,而gcc是通用C编译器。
#3
0
This actually relates to the classic C&R hello world snippet:
http://en.wikipedia.org/wiki/Hello_world#History
这实际上与经典的C&R hello世界片段有关:http://en.wikipedia.org/wiki/Hello_world#History
#1
3
In C (prior to C99), you don't have to declare functions in order to use them. The compiler will assume the function takes the promoted parameter types you pass to it, and assume the function returns an int
. This, however can be quite problematic, and behavior is undefined if the function doesn't. Let's look at this:
在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);
}
Because the types are being promoted (char -> int, float -> double
) if there is no declaration of the function at the time you call it, the arguments could not be passed at the right places in memory anymore. Accessing b can yield to a curious value of the parameter. As a side node, the same problem occurs when you pass arguments to vararg functions
like prinft
, or functions having no prototype (like void f()
, where there is no information about the parameters types and count). This is the reason that you always have to access variadic arguments with va_arg
using their promoted type. GCC will warn you if you don't.
因为正在提升类型(char - > int,float - > double),如果在调用它时没有函数声明,则参数不能再在内存中的正确位置传递。访问b可以产生参数的奇怪值。作为一个副节点,当您将参数传递给vararg函数(如prinft)或没有原型的函数(如void f(),其中没有关于参数类型和计数的信息时)会出现同样的问题。这就是您始终必须使用其提升类型使用va_arg访问可变参数的原因。如果你不这样做,GCC会警告你。
Always include the proper header files, so you don't run into this problems.
始终包含正确的头文件,因此您不会遇到此问题。
Edit: thanks to Chris for pointing out that char literals
(like 'a'
) are always of type int
in C
编辑:感谢Chris指出char文字(如'a')在C中始终是int类型
#2
5
glClearColor isn't a macro so you don't need the headers to define it. If you add warnings:
glClearColor不是宏,因此您不需要标头来定义它。如果添加警告:
gcc -o test -Wall -W test.c -framework GLUT -framework OpenGL
Then you'll get a warning about the implicit declaration of glClearColor. You also won't be able to use any macros as the compiler will give you an error that they are undefined. Since the glClearColor symbol gets properly resolved by the linker, you never get an error.
然后你会得到关于glClearColor的隐式声明的警告。您也将无法使用任何宏,因为编译器会给您一个未定义的错误。由于glClearColor符号由链接器正确解析,因此您永远不会收到错误。
It also occurs to me that you might have been wondering this because you thought you were compiling for C++. The example you gave actually compiles C code where it is not an error to fail to declare function prototypes. If you meant to compile this as C++ code, you would need the following command line:
我也想到你可能一直在想这个,因为你以为你在编译C ++。您提供的示例实际上编译了C代码,其中未能声明函数原型并不是错误。如果您打算将其编译为C ++代码,则需要以下命令行:
g++ -o test test.cpp -framework OpenGL
g ++ -o test test.cpp -framework OpenGL
In that case you most certainly would get an error for not including gl.h and your code would fail to compile. When executing GCC from the command line, g++ is the C++ compiler while gcc is the general C compiler.
在这种情况下,你肯定会因为不包括gl.h而出错,你的代码将无法编译。从命令行执行GCC时,g ++是C ++编译器,而gcc是通用C编译器。
#3
0
This actually relates to the classic C&R hello world snippet:
http://en.wikipedia.org/wiki/Hello_world#History
这实际上与经典的C&R hello世界片段有关:http://en.wikipedia.org/wiki/Hello_world#History