Является ли хорошей идеей использовать указатель const для типа FILE?

saxbophone спросил: 28 марта 2018 в 04:42 в: c

Обычно C-файл ввода-вывода выполняется с помощью FILE*, поскольку это то, что берут на себя функции стандартной библиотеки.

В C также может быть const указатель , где адрес указателя не может измениться (но значение, на которое оно указывает, может быть).

Я задавался вопросом, можно ли это применить к FILE*, поэтому написал эта небольшая программа для проверки этого:

#include <stdio.h>int main(void) {
    FILE* const file = fopen("somefile.txt", "w");
    if (file != NULL) {
        fprintf(file, "%s\n", "So this works? That's just swell!");
    }
    return 0;
}

Это компилируется отлично и работает по назначению на Ubuntu / Linux 16.04 с использованием GCC (файл содержит точно строку, которую я ожидал), но я не уверен, что эта идиома является такой хорошей идеей - тип FILE непрозрачен по дизайну, а обработка его специфична для реализации.

Потому что нет никакой гарантии, что любая реализация библиотеки C выиграла Не пытайтесь изменить адрес указателя FILE, безопаснее ли использовать этот подход при выполнении ввода / вывода в C?

1 ответ

Есть решение
Jonathan Leffler ответил: 28 марта 2018 в 05:24

Преобразование комментариев в ответ по запросу.

Вы можете использовать FILE * const sanely; Вы не можете использовать const FILE * разумно. Существует гарантия, что ни одна из функций в библиотеке C не изменит указатель части FILE *, которую вы им передаете, каким-либо образом, обнаруживаемым вызывающим кодом, потому что указатель всегда передается по значению - никогда адрес указателя. Таким образом, вызывающий код не может изменить ваш указатель - если только он не идет на безумно сложные шаги, чтобы сделать это, и не будет, потому что в этом нет никакой необходимости и никакой выгоды.

Мне известно о разнице между FILE * const и const FILE * (а также о том, почему последнее не имеет никакого смысла). В моем вопросе я пытаюсь уточнить, окажет ли создание указателя const какое-либо негативное влияние на стандартные библиотечные функции, так как они не используют указатели const в своих прототипах.

Кроме того, для контекста, почему я Я пытаюсь это сделать - по тем же причинам, по которым можно заставить любой другой указатель const: остановить случайное переназначение того, на что он указывает.

Это не может иметь никакого эффекта о функциях в библиотеке; им передают копию значения, и они не будут изменять значение, но не будут знать, что исходное значение в любом случае не подлежит изменению, и им все равно. Использование FILE * const fp = fopen(…); просто означает, что вы не можете повторно использовать этот указатель файла для чего-либо еще в той же функции (или повторить попытку открытия другого имени файла или вызова другой функции 'open'), и вы не можете сбросить его NULL после того, как вы fclose() это. Конечно, если указатель выходит из области видимости, потому что он находится внутри цикла, его можно использовать повторно при повторном вводе области.

В противном случае использование FILE * const не имеет никакого эффекта. Я не думаю, что это полезно. Это не вредно, за исключением того, что оно не приносит никакой пользы (и может запутать людей). Я не рекомендую использовать FILE * const.

user3386109 ответил: 28 марта 2018 в 05:12
Одна хуза для последнего абзаца.
saxbophone ответил: 29 марта 2018 в 08:41
Да, спасибо - последний бит особенно полезен. Я думаю, что буду следовать вашей рекомендации, это имеет смысл.