2017-01-25 3 views
1

Чтобы иметь более чистый способ проверки определенных функций, я хотел бы провести тесты по функции fclose. Но у меня была проблема при попытке написать и перечитать образ растрового изображения.Неисправность проверки fclose возвращаемое значение

На самом деле, у меня была ошибка произошедшей при тестировании fclose так:

assert(fclose(bmp_image) != EOF); 

Хотя следующий код не дает ошибку:

int closing_ok = fclose(bmp_image); 
assert(closing_ok != EOF); 

С большим количеством тестов, я видел это разница происходит только в режиме записи, но не в режиме чтения. Нормально ли такое различие происходит? Может ли кто-нибудь объяснить мне эту разницу?

EDIT: Я попытался получить ошибку смысл с этим кодом:

if(fclose(output_file) != EOF) { 
    printf("ERROR: %s\n", strerror(errno)); 
} 

Но это также хорошо здесь и нет ошибок.

+0

Что вопрос именно? Разве это просто не вызвало? – StoryTeller

+0

@StoryTeller Я полагаю, что это так. Он может не закрыть файл правильно ... Это не так уж и важно, я просто не понимаю этого поведения. – baptiste

+0

Ваш тест в 'if (fclose (output_file)! = EOF)' должен, вероятно, быть 'if (fclose (output_file) == EOF)' для печати причины ошибки. – Gerhardh

ответ

3

assert - макрос, который заменяется на no op при компиляции с NDEBUG. Грубо говоря, если вы создадите версию своего исполняемого файла, весь код fclose будет удален из кода.

Это возможная причина, по которой файлы могут быть закрыты неправильно.

+0

В этом проблема. В режиме Release с cmake нет закрытия файла вообще ... – baptiste

2

assert() должен использоваться со скалярным выражением. Это означает, что вы не должны использовать в нем функцию.

Вы получаете это поведение, потому что fclose(bmp_image) оценивается дважды. Поэтому он возвращает EOF во втором вызове, потому что файл уже закрыт.

Вы можете проверить с этим:

int my_fclose(FILE *file) { 
    int ret = fclose(file); 
    if (ret == EOF) { 
    printf("ERROR: %s\n", strerror(errno)); 
    } 
    else { 
    printf("no problem\n"); 
    } 
    fflush(stdout); 
    return ret; 
} 

int main(void) { 
    // bad 
    assert(my_fclose(bmp_image) != EOF); 
} 
+0

В чем разница с кодом в вопросе? Вы также вызываете функцию в assert. И если определено 'NDEBUG', ваша функция' my_fclose' также не называется вообще. – Gerhardh

+0

@Gerhardh Это всегда печатает что-то, чтобы OP мог видеть, что функция вызывает вызов дважды. Возможно, добавьте 'fflush (stdout);'. Быть уверенным. – Stargateur

Смежные вопросы