Вопрос

Как я отправил объявление FILE * в с? Я обычно делаю это, используя struct MyType;, но, естественно, это не может быть возможно.

Если поведение отличается между стандартами или компиляторами C и с C ++, это также интересно.

Update0.

Почему я хочу сделать это в сторону: то, что я спрашиваю, - это то, как переслать объявить неструктуру / «Typedef'd struct», чтобы я мог объявить указатели к нему. Очевидно, используя void * и лить его в исходном файле немного взлома.

Это было полезно?

Решение

Вы не можете. Стандарт только говорит, что FILE это «тип объекта, способный записывать всю информацию, необходимую для управления потоком»; Это зависит от реализации, является ли это typedef а. struct (чье имя вы все равно не знаете), или что-то еще.

Единственный портативный способ объявить FILE это с #include <stdio.h> (или <cstdio> в C ++).

Другие советы

если ты #include <stdio.h> Вы должны получить FILE Typedef с этим. Это единственный действительно безопасный и портативный путь - вы не можете иметь Typedef без типа псевдоним, и нет никакой гарантии о том, какой тип FILE псевдонимы, так что каждый компилятор или LIBC или все, что может иметь другой. Но вам понадобится правильный тип, если кто-то на самом деле хочет #include <stdio.h>, чтобы нерешительные определения не вызывают ошибки.

Редактировать:

Теперь, когда я думаю об этом, может быть еще один способ, которым я могу думать. Это не типичный файл, это злые макросы, которые работают, угнатим определение «файла». Я бы не рекомендовал это только по этой причине. Но это может работать за то, что вам нужно.

#ifdef USES_REAL_FILE_TYPE
#include <stdio.h>
#else
#define FILE void
#endif

/* declare your struct here */

#ifndef USES_REAL_FILE_TYPE
#undef FILE
#endif

Затем #define USES_REAL_FILE_TYPE Прежде чем включить файл в любой код, где вам нужен реальный FILE *, а остальная часть кода просто увидит указатель как void *.

Я не гарантирует, что это не будет беспорядок. В частности, он сломается в любом случае, когда вы хотите знать что-либо реальное о таком поддельном типе, и весь код, который касается указателя, может понадобиться, что #define. Но если вы мертвы набор против «ненужных» #InCludes, это единственный способ получить FILE * не вмешиваясь со Stdio. Вы не сможете переслать объявить Typedef.

Редактировать2:

Хорошо, я проверил просто, чтобы убедиться. Не уверен, насколько это стандарт, или что вы можете сделать с этим, но ...

typedef FILE;

Работает в Visual C и GCC оба, но Только При компиляции C код. Похоже, что стандарт C ++ явно говорит где-то, что вы не можете иметь Typedef без типа. К одно, хотя, не так.

Однако, похоже, не позволяют типу, чтобы быть объявленным вперед, не в GCC в любом случае. Если вы попытаетесь typedef int FILE; Сразу после этого бросает ошибку об конфликтующих типов. ВС, однако, кажется, позволяют ему, пока это до целочисленного типа. Кажется typedef X действительно значит typedef int X в против (и, по-видимому, в C99). В любом случае GCC не позволит вам повторить Typedef даже к точному типу.

FILE Это Typedef вокруг структуры, которую вы не должны исследовать слишком много (например, вы не должны играть с данными обработки WinAPi), если только через его выделенную функцию API.

Форвардный заявляющий?

Передовая декларирование позволяет объявить указатель (или на C ++, ссылку) к типу и имея эту декларацию с компиляцией до тех пор, пока символ не используется (например, вперед-объявление символа в вашем заголовке, а затем, включая Заголовок, где символ правильно объявлен в источнике, используя его).

Таким образом, форвардный декларинг включает в себя означает:

  • Быстрее компиляция
  • меньше муфты

Патрон Typedef vs. Flow-Jukning?

Проблема с помощью Typedefs состоит в том, что они являются болью, чтобы справиться, потому что, как вы обнаружите, вы не можете переслать - объявить их.

Так что вы не можете переслать - объявить FILE, ни вы не можете переслать - объявить std::string. Отказ Таким образом, у вас нет выбора, но в том числе заголовка для обработки их.

(Это причина, по которой я ненавижу typedef struct { /* ... */ } MyTypedefedType ; Узор от C Invading C ++ код: это бесполезно в C ++, и предотвращает прямое объявление.)

Предполагается объявление стандартных символов?

Хорошей частью является то, что если символы являются «стандартами», это не должно быть слишком большим, чтобы включить их заголовок. Муфта не так много проблем, и если она несколько замедляет компиляцию, даже что может быть безболезненным благодаря использованию предварительнокомпомянутых заголовков.

<iosfwd> : Некоторые люди думали о вас!

Стандартная библиотека C ++ предлагает <iosfwd> заголовок

Вместо того, чтобы включить любые (или все) заголовки потоков C ++, вы можете включить <iosfwd> Если то, что вам нужно, это только передовая декларация.

FILE является системой зависимой typedef. Отказ Ты не допускается Ухаживание, как фактическая структура определяется или даже названа. Но вы всегда можете смотреть в свой /usr/include/stdio.h файл :)

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

Тем не менее, можно изменить интерфейс собственного объекта, чтобы полагаться на простое целые числа, а затем использовать Fileno. Функция (также доступна через #include <stdlib.h>).

Подробные шаги
0. Найдите свой текущий интерфейс. Например:
    void myprint(FILE* stream, ...);
1. Используйте целочисленный файл дескриптора (FD) вместо FILE*:
    void myprint(int stream_fd, ...);
2. Вызовите новый интерфейс с fileno вместо FILE*:
    myprint(fileno(stream));

Недостаток, однако, что ваша реализация (myprint В приведенном выше примере) необходимо переписать с помощью файлового дескриптора вместо FILE* для фактических процедур ввода / вывода. Альтернативой переписывающей реализации является просто fdopen а. FILE используя данный дескриптор.

void myprint(int stream_fd, ...)
{
  FILE *const stream = fdopen(stream_fd);
  /* your existing implementation follows */
  fclose(stream);
}

Вышеуказанное в свою очередь приводит к тому, что вы думаете о том, где «владеть» ресурсом, чтобы закрыть FILE когда больше не нужно. Часто открытая / тесная последовательность просто отлично (как показано выше), однако, в более сложных случаях необходимо отрегулировать реализацию (которую мы пытались избегать), открыв файл с помощью режима добавления и т. Д.

Файл * - непрозрачный тип. Таким образом, это должно в теории работать.

typedef struct FILE_impl_but_including_stdio_h_is_best FILE;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top