Функция Variadic, вызывающая сигнал SIGILL с перечислениями - PullRequest
0 голосов
/ 31 января 2012

Можно ли передать перечисление в качестве параметра в функцию с переменными числами? Я пытаюсь сделать следующее:

GLenum ShaderManager::initialize()
{
    GLuint program = loadShader("Flat", 2, ATTRIBUTE_VERTEX, "coord3d", ATTRIBUTE_TEXTURE0, "texcoord");

    //...
}


GLuint ShaderManager::loadShader(std::string shaderName, ... )
{
    GLuint program;

    //...

    va_list arglist;
    va_start(arglist, shaderName);

    int count = va_arg(arglist, int);
    for(int i = 0; i < count; i++) {
        AttributeLocation location = va_arg(arglist, AttributeLocation);
        char * name = va_arg(arglist, char *);
        glBindAttribLocation(program, location, name);
    }
    va_end(arglist);

    //...
}

Где ATTRIBUTE_VERTEX и ATTRIBUTE_TExTURE объявлены как

enum AttributeLocation {
        ATTRIBUTE_VERTEX = 0,
        ATTRIBUTE_COLOR,
        ATTRIBUTE_NORMAL,
        ATTRIBUTE_TEXTURE0
    };

Но программа просто завершается. При отладке программы я обнаружил, что ошибка возникает в первой строке после цикла for. Поэтому мне интересно, возможно ли это сделать или это что-то незаконное.

1 Ответ

3 голосов
/ 31 января 2012

Это связано с тем, что передача целочисленных типов размером менее sizeof(int) байтов в функцию varargs преобразует их до sizeof(int) байтов при передаче в стек.Если AttributeLocation меньше sizeof(int) байтов, то sizeof(int) байтов помещается в стек, но вы извлекаете только sizeof(AttributeLocation) байтов из стека с помощью вызова va_arg.Затем, когда вы пытаетесь прочитать char*, вы получаете остальные байты AttributeLocation и некоторые байты const char*, которые вы прошли.

...