C ++ inline methods with the same if statements

I use a handler for OpenGL texture, and I think about security and performance. What level of optimization should remove marked if statements?


struct Texture2D {
    GLuint ID;

    inline Texture2D(): ID(0) {};
    inline explicit Texture2D(GLuint id): ID(id) {};
    ~Texture2D();

    void GenTexture(bool regen = false);
    void DeleteTexture();

    void BindTexture();

    void Parameterf( GLenum pname, GLfloat param );
    void Parameteri( GLenum pname, GLint param );
    void glTexParameterfv( GLenum target, GLenum pname, const GLfloat *params );
    void glTexParameteriv( GLenum target, GLenum pname, const GLint *params );

    static Texture2D binded;
};
inline void Texture2D::GenTexture(bool regen) {
    if(ID){
        if(regen)
            DeleteTexture();
        else
            return;
    }

    glGenTextures(1,&ID);
}

inline void Texture2D::DeleteTexture() {
    glDeleteTextures(1,&ID);
    ID = 0;
}

inline void Texture2D::BindTexture() {
    glBindTexture(GL_TEXTURE_2D, ID);
    binded.ID = ID;
}

inline void Texture2D::Parameterf( GLenum pname, GLfloat param ){
    if(binded.ID == ID)                          // THIS
        BindTexture();                           // THIS

    glTexParameterf(GL_TEXTURE_2D,pname,param);
}

inline void Texture2D::Parameteri( GLenum pname, GLint param ){
    if(binded.ID == ID)                          // THIS
        BindTexture();                           // THIS

    glTexParameterf(GL_TEXTURE_2D,pname,param);
}

inline Texture2D::~Texture2D() {
    DeleteTexture();
}

// in this function
void loadTexture(...) {
    Texture2D t;
    t.GenTexture();
    t.BindTexture();
    // if statements in next functions
    t.Parameterf(...);
    t.Parameterf(...);
    t.Parameterf(...);
    t.Parameterf(...);
    t.Parameterf(...);
}
+3
source share
3 answers

Missing.

It's a sad story, but C ++ suggests that if you call a function, this function can cause all kinds of side effects, including changing the value of binded.ID (that the function somehow knows)

With the exception of

, bindend.ID, ( ), ( - ). (, side_effect() )

int side_effect();
int k=1; 

int main()
{
    side_effect(); 
    if (k!=0) return 0;
    side_effect(); 
    if (k!=0) return 0;
    side_effect(); 
    if (k!=0) return 0;
}

side_effect() k , . side_effect.

int side_effect();
static int k=1; 

int main()
{
    side_effect(); 
    if (k!=0) return 0;
    side_effect(); 
    if (k!=0) return 0;
    side_effect(); 
    if (k!=0) return 0;
}

, side_effect k , . side_effect(); return 0, k , side_effect() . , undefined.

int side_effect();
void snitch(int*);

static int k=1; 

int main()
{
    snitch(&k); // !!!
    side_effect(); 
    if (k!=0) return 0;
    side_effect(); 
    if (k!=0) return 0;
    side_effect(); 
    if (k!=0) return 0;
}

, snitch() , side_effect() , side_effect() .

, k : , k , k.

PS: k const , const. const-ness .

+4

, - .

+2

No level of optimization can (correctly) remove these tests. They could only be removed if both arguments were compile-time constants and none of them were, or if the compiler can prove that they will not change the value between the tests.

Since it bindedis static, the compiler cannot know that calls to GL functions will not change it.

+2
source

Source: https://habr.com/ru/post/1758019/


All Articles