LINUX.ORG.RU

Интересное поведение gcc

 , ,


0

1

http://pastebin.com/yWVCBBVM Компилировал с gcc: gcc 33.c -o 33 -g, segfault С tcc: tcc -run 33.c, segfault Не сегфолтится, если компилировать так: gcc 33.c -o 33 -g -Os

При отладке заметил, что на строке 9 (fscanf) указатель на файл output меняет свое значение (адрес) с 0x601215 (у меня) на 0x600000...

Это как надо было наоптимизировать код, чтобы указатель файловый съезжал? Или в коде ошибка?



Последнее исправление: cetjs2 (всего исправлений: 1)
Ответ на: комментарий от ms-dos64
#include <stdio.h>
int main(void)
{
	FILE* input=fopen("input.txt","r");
	FILE* output=fopen("output.txt","w");
	char c;
	while( (c=fgetc(input))!=EOF ){fputc(c,output);}
	fclose(input);
	fclose(output);
	return 0;
}

Вот эта работает, fgetc тоже EOF возвращает

ms-dos64
() автор топика

Обычно, если чё-то не работает, сначала лучше проверить свой код, перед тем как браться за другой компилятор:

$ gcc -Wall -g -o test_fscanf_segfault test_fscanf_segfault.c 
test_fscanf_segfault.c: In function ‘main’:
test_fscanf_segfault.c:10:2: warning: format ‘%u’ expects argument of type ‘unsigned int *’, but argument 3 has type ‘short unsigned int *’ [-Wformat]
test_fscanf_segfault.c:10:2: warning: format ‘%u’ expects argument of type ‘unsigned int *’, but argument 4 has type ‘short unsigned int *’ [-Wformat]
$ 
Если исправить, то всё работает.

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

Да, их там ровно 2. Всегда. Поэтому и проверки нет

ms-dos64
() автор топика
Ответ на: комментарий от gag

Верно, считанная инфа просто не влезала. Но я скормил проге 2 числа: 5 и 6. Они-то почему не лезут? если собирать с -Os, то все работает как надо

ms-dos64
() автор топика

Или в коде ошибка?

В коде... днк. Вот скажи, почему я, не зная си вообще, за 5 минут нашел, что не так и как это исправить, не обращаясь ни к кому за помощью?

anonymous
()
Ответ на: комментарий от arsi

Я понял ошибку («%u» подразумевает unsigned int), но почему это действовало на указатель output?

ms-dos64
() автор топика
Ответ на: комментарий от ms-dos64

Почему сразу не лезут? Так и лезут каждый в два байта памяти как 00000005 и 00000006, затирая по два байта случайной рядом расположенной памяти.

kim-roader ★★
()
Ответ на: комментарий от ms-dos64

Блин, ну в манах же все написано, что непонятно-то?

h Indicates that the conversion will be one of d, i, o, u, x, X, or n and the next pointer is a pointer to a short int or unsigned short int (rather than int).

theNamelessOne ★★★★★
()
Ответ на: комментарий от kim-roader

Если бы у меня был массив unsigned short int и я бы в них так писал, то произошел бы локальный стек-капец... блин

ms-dos64
() автор топика

Спасибо всем, в след. раз буду за памятью следить

ms-dos64
() автор топика
Ответ на: комментарий от ms-dos64

Я компилирую свои велосипеды с

-Wall -Wextra -Werror -std=STD_PLACEHOLDER   -pedantic-error

время от времени выключая некоторые, ошибки, например, неиспользуемые параметры функций:

-Wno-error=unused-parameter

и мои волосы теперь мягкие и шелковистые

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

насколько я понимаю, поиск символа в строке в printf/scanf происходит через strchr или аналогичным образом, так что порядок символов в строке не имеет значения. И еще ты ответил на удаленный комментарий

ms-dos64
() автор топика
Ответ на: комментарий от ms-dos64

поиск символа в строке в printf/scanf происходит через strchr или аналогичным образом, так что порядок символов в строке не имеет значения.

нет, все-таки ты упорот. strchr? Как ты это себе представляешь?

Опять отправляю тебя в ман:

· An optional '*' assignment-suppression character: scanf() reads input as directed by the conversion specification, but discards the input. No corresponding pointer argument is required, and this specification is not included in the count of successful assignments returned by scanf().

· An optional 'a' character. This is used with string conversions, and relieves the caller of the need to allocate a corresponding buffer to hold the input: instead, scanf() allocates a buf‐ fer of sufficient size, and assigns the address of this buffer to the corresponding pointer argument, which should be a pointer to a char * variable (this variable does not need to be ini‐ tialized before the call). The caller should subsequently free(3) this buffer when it is no longer required. This is a GNU extension; C99 employs the 'a' character as a conversion speci‐ fier (and it can also be used as such in the GNU implementation).

· An optional decimal integer which specifies the maximum field width. Reading of characters stops either when this maximum is reached or when a nonmatching character is found, whichever happens first. Most conversions discard initial white space characters (the exceptions are noted below), and these discarded characters don't count toward the maximum field width. String input conversions store a terminating null byte ('\0') to mark the end of the input; the maximum field width does not include this terminator.

· An optional type modifier character. For example, the l type modifier is used with integer conversions such as %d to specify that the corresponding pointer argument refers to a long int rather than a pointer to an int.

· A conversion specifier that specifies the type of input conversion to be performed.

type modifier должен идти до conversion specifier, а не наоборот. Если поменять их местами (т.е. использовать «%uh»), то получим форматную строку, которая сначала ожидает указатель на unsigned int, а затем ждет совпадения с символом 'h'.

theNamelessOne ★★★★★
()
Ответ на: комментарий от ms-dos64

так что порядок символов в строке не имеет значения.

:3 assumption is the mother of all fuck-ups

Представь, как бы ты реализовал эту фичу. Первое, что нужно искать, это спецсимвол %, нашли, теперь парсим все, что идет после него. А идти может последовательность символов, и казалось бы, можно и считывать символы по одному и сравнивать их наборы, но это лишнее, к тому же убивает возможность давать разные функции для hu и uh. Так что сравниваются строки.

anonymous
()
Ответ на: комментарий от ms-dos64

Без разницы, модификаторы считываются и запихиваются в набор модификаторов, но это не значит, что форматная строка разбирается точно так же.

anonymous
()
Ответ на: комментарий от ms-dos64

Не принимай мое слово на веру, я понятия не имею о чем говорю =)
Читай исходный код и книжки же.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.