为什么程序员在OpenGL中使用常量和静态变量?

时间:2012-08-21 23:00:43

标签: opengl static const

我注意到程序员创建变量conststatic。我理解这些关键字的作用,但我不知道他们为什么要使用它们。


示例1
from The Official Guide to Learning OpenGL, Version 1.1 Chapter 2

    static GLint vertices[] = {25, 25,
                              100, 325,
                              175, 25,
                              175, 325,
                              250, 25,
                              325, 325};

    static GLfloat colors[] = {1.0, 0.2, 0.2,
                              0.2, 0.2, 1.0,
                              0.8, 1.0, 0.2,
                              0.75, 0.75, 0.75,
                              0.35, 0.35, 0.35,
                              0.5, 0.5, 0.5};

    glEnableClientState (GL_COLOR_ARRAY);
    glEnableClientState (GL_VERTEX_ARRAY);

    glColorPointer (3, GL_FLOAT, 0, colors);
    glVertexPointer (2, GL_INT, 0, vertices);

为什么世界上这些数组只有在这个单一对象实例中使用时才必须是静态的?


示例2
from OpenGL Programming on wikibooks tutorial 1

    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);

    const char *fs_source =
    "#version 120           \n"
    "void main(void) {        "
    "  gl_FragColor[0] = 0.0; "
    "  gl_FragColor[1] = 0.0; "
    "  gl_FragColor[2] = 1.0; "
    "}";

    glShaderSource(fs, 1, &fs_source, NULL);

fs_source char数组在设置后不会被更改。但它是否绝对必须使它保持不变?它会提高性能吗?

3 个答案:

答案 0 :(得分:4)

  

我了解这些关键字的作用,

你呢?

  

但我不知道他们为什么要使用它们。

你呢?!

  

为什么世界上这些数组只有在这个 对象实例 中使用时才必须是静态的?

什么对象?什么实例?你引用这个例子的书是用C语言编写的,而不是用C ++编写的,尽管用C语言实现对象和实例是完全可能的,但语言本身没有内置的那些定义。因此我认为你对< em> static 在这种情况下确实是错误的。

在给定的示例中,如果 static 在模块级别应用于全局变量。这样做的结果是,变量只对其定义的编译单元可见。在C程序中,通常和推荐的做法是声明在当前编译单元之外不被引用的所有静态。

在函数范围内对常量数据使用static可以节省每次调用函数时完成变量初始化的开销。

  

fs_source char数组在设置后不会更改。

你真的不能。 C语言指定不属于 char 数组初始化的字符串文字属于const char *类型,并且位于程序映像的专用只读段中。由于非初始化字符串文字的类型为const char *,因此将此类指针变量分配给char *会调用未定义的行为。

  

但绝对有必要让它保持不变吗?

尝试删除 const 并使用-Werr编译程序时会发生什么。这实际上是语言正确性的问题。

答案 1 :(得分:3)

是的,通常情况下, 会提高性能,但必然以您想象的方式。

通过这些提示,编译器可以自由选择不同的优化(空间和时间),使代码在此过程中更有效。

例如,静态存储持续时间变量(a)在程序启动时初始化一次,永远不必再次初始化。

将某些内容标记为const允许编译器生成更高效的代码,并充分了解数据不会更改。作为一个极端的例子,它可以将值加载到专用CPU寄存器中,而不再查看内存中的数据。

所以是的,它可以提高性能,不是因为封面下的相同指令运行得更快,而是因为编译器可以根据你给出的额外知识自由使用不同的指令。


(a):假设你拥有static的含义。还有一些关键字用于限制其可见性范围,这是良好的编程习惯。

答案 2 :(得分:1)

在我们讨论的文件中,varray.c(例1):

示例中的静态不是在模块级别声明的,它们的可见性仅在函数内部。 static关键字在不同的时间可能意味着不同的东西,但在这种情况下,它不是要限制它们与其他代码文件的可访问性(但是通过将它们的范围限制为仅在任何情况下发生的功能)。

在程序运行期间,这些数组仅被声明/生成一次。在这些声明之前添加static关键字(例如在setupPointers中)意味着那些代码行(59-64,65-70)只执行一次,指针本身不会改变,这些数字不必“再次流过管道(参见上面的回答表现),因为它们已经存在。

这是因为当用户单击鼠标按钮时,程序在两个绘图例程之间切换。仅将数组初始化一次而不是每次调用setupPointers函数都是有意义的。

所以,这是static关键字的工作方式之一,它告诉编译器只初始化此变量一次。 const类似,但更像是“只写一次这个记忆”。

你可能会说,那么为什么不让它们成为常量?我知道,对吧?

也许这些链接可以帮助人们:

varray.c

a blog post about the static keyword