Писал примитивную програмку на Си, курсач для знакомой, но это не важно. Есть
там кусок кода, который читает записи из файла: первая строка -- количество
записей, последующие -- собственно "полезные" записи.

Вот кусок кода:

        size_t n /*= 0*/;
        /* тут пропущены проверки переданных в ф-ю параметров */
        fscanf(f, "%u", &n);
printf("n==%u\n", n); /* для отладки */
        if ((n > K_MAX_ITEMS) || (n == 0))
        {
printf("ERROR: n==%u\n", n); /* тжс */
                *error = K_BAD_SIZE;
                goto quit;
        }

        if ((stab = malloc(n * sizeof(Stab))) == NULL)

Код проверки if ((n > K_MAX_ITEMS) || (n == 0)) работает некорректно! Т.е.
fscanf читает из файла, напр., 3, printf его выводит, а if возвращает true,
хотя должен false (K_MAX_ITEMS==1024)! Если убрать этот if, то malloc не может
выделить память (для n==3 всего лишь 432 байта).

А если инициализировать n в 0 (в декларации, или перед fscanf), то всё работает
правильно. Собирал и с -O2 и с -O0, результат один и тот же. Ассемблерный код
для вариантов с инициализацией в 0 и без неё отличается ровно 1 инструкцией
(movq $0, -40(rbp)).

Если сделать так: if (/*(n > K_MAX_ITEMS) ||*/ (n == 0)), то облом на malloc.
Если так: if ((n > K_MAX_ITEMS) /*|| (n == 0)*/), то на этом if.

В принципе, не важно во что инициализирована n, важен сам факт инициализации.

Виноват ли gcc-4.3.real (Debian 4.3.2-1.1) 4.3.2, или что-то другое? Может
процессор не видит связи между участками кода и распаралеливает неправильно? У
меня amd64, возможно проблема в этом, т.к. параметры в функции передаются не
через стэк, а через регистры.

Собрал для проверки mingw32 -- работает правильно.

-- 
 http://375gnu.wordpress.com


-- 
To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: http://lists.debian.org/20100314082154.ga3...@globus

Ответить