[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

GCC генерирует неправильный код?



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

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

	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


Reply to: