我有点困惑为什么这段代码编译。我省略了“必要的”#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只是指定了库所在的链接器,但我认为我仍然需要标题?
答案 0 :(得分: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编译器。
答案 1 :(得分: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
(如prinft
或没有原型的函数(如void f()
)时,会出现同样的问题,其中没有关于参数类型和计数的信息)。这就是您始终必须使用其提升类型访问va_arg
的可变参数的原因。如果你不这样做,海湾合作委员会会警告你。
始终包含正确的头文件,因此您不会遇到此问题。
修改:感谢Chris指出char literals
(如'a'
)在C中始终为int
类型
答案 2 :(得分:0)
这实际上与经典的C&amp; R hello世界片段有关:
http://en.wikipedia.org/wiki/Hello_world#History