LINUX.ORG.RU

Глюк с инициализацией глобальных переменных (C/mingw)

 , , , ,


0

3

Всех приветствую!

Обнаружилось непонятное явление: после компиляции mingw32 и запуска под wine в программе не инициализируются глобальные переменные.

Более подробно:

Глобальные переменные:

bool line_mode = false;
enum {ORTHOGRAPHIC=0, PERSPECTIVE};
int projection_type=ORTHOGRAPHIC;

Некоторые ф-ции:

void reshape_cb (int w, int h)
{
    glViewport ( 0, 0, (GLint) w, (GLint) h ) ;
    WIDTH = w;
    HEIGHT = h;

       
    printf("projection_type = %d\n", projection_type);
    printf("line_mode = %d\n", line_mode);
    switch ( projection_type )
    {
      case PERSPECTIVE:
        printf("PERSPECTIVE\n");
        ...        
        break;

      case ORTHOGRAPHIC:
        printf("ORTHOGRAPHIC\n");
        ...
        break;
    };

    ...
    CHECK_GL_ERROR(); 
    printf("reshape()\n");
}
void keyboard_cb ( unsigned char key, int x, int y )
{
    switch ( key )
    {
      case 'l' :
      case 'L' :
      {
          line_mode = !line_mode;
          break;
      }

      case '1' :
      {
          projection_type = ORTHOGRAPHIC;
          reshape_cb(WIDTH, HEIGHT);
          break;
      }

      case '2' :
      {
          projection_type = PERSPECTIVE;
          reshape_cb(WIDTH, HEIGHT);
          break;
      }

      ...

    };

    glutPostRedisplay();
}

После запуска wine program.exe на экран выдается

projection_type = -1122261533
line_mode = 100
reshape()

При компиляции gcc все нормально:

projection_type = 0
line_mode = 0
ORTHOGRAPHIC
reshape()

Лечится это явление добавлением static:

static bool line_mode = false;
enum {ORTHOGRAPHIC=0, PERSPECTIVE};
static int projection_type=ORTHOGRAPHIC;

(или, возможно, инициализацией в ф-ции main) Тогда правильно работает и после mingw.

Кто-нибудь сталкивался с таким явлением? Почему это происходит?

Добавление.

Если после запуска wine program.exe нажать клавишу [2], то

projection_type = -1122261533
line_mode = 100
reshape()
НАЖАТИЕ КЛАВИШИ [2]
projection_type = 1
line_mode = 100
PERSPECTIVE
reshape()

видно значение projection_type инициализировалось как и задумано.

Тоже самое после gcc: ./program

projection_type = 0
line_mode = 0
ORTHOGRAPHIC
reshape()
НАЖАТИЕ КЛАВИШИ [2]
projection_type = 1
line_mode = 0
PERSPECTIVE
reshape()

PS Заранее благодарю за осмысленные ответы.

PS2 К сожалению, сделать маленький пример на выдачу этой ошибки пока не удалось. А вываливать кучу файлов сюда неуместно. Могу exe-шник дать для анализа явления.



Последнее исправление: Gyros (всего исправлений: 1)
Ответ на: комментарий от MKuznetsov

Вообще в .h должны быть только декларации (по сути типы, константы и заголовки функций). Если там светится переменная - всё, дальше будет говна по коду вагон и еще четыре вагона сверху.

no-dashi-v2 ★★★
()
Ответ на: комментарий от Gyros

Чтобы не ловить по всему коду, где вылезли за пределы переменной типа MAT3, лучше как раз оставить только

typedef struct MAT3 
{
    float M00, M10, M20, 
          M01, M11, M21, 
          M02, M12, M22;
} MAT3;

Да, это может оказаться не удобным, но зато не вылезешь за границу.

Vic
()
Ответ на: комментарий от Gyros

Я вот что подумал, может глобальные всегда объявлять со static?

глобальный статик в файле с main() лишнее, поскольку оно и так статическую жизнь имеет, static в таком случае не будет делать ничего — его действие было бы оправдано в какой либо библиотеке, которая линковалась бы (в том числе к объектнику с main()) — если нужно было бы отменить видимость переменных/констант вне объектника.

safocl ★★
()
Ответ на: комментарий от alysnix

тогда как си дает тебе возможность вести статически контроль за этим. то есть компилятор бы ругнулся, если бы код написал правильно.

это чем же он даёт такую возможность?

safocl ★★
()