Нет, они не то же самое. Например:
#define INTPTR int*
...
INTPTR a, b;
После предварительной обработки эта строка расширяется до
int* a, b;
. Надеемся, вы увидите проблему; только a
будет иметь тип int *
; b
будет объявлен простой int
(поскольку *
связан с объявлением, а не с спецификатором типа).
Контрастность с
typedef int *INTPTR;
...
INTPTR a, b;
В этом случае оба a
и b
будут иметь тип int *
.
Существуют целые классы typedefs, которые нельзя эмулировать с помощью макроса препроцессора, например указатели на функции или массивы:
typedef int (*CALLBACK)(void);
typedef int *(*(*OBNOXIOUSFUNC)(void))[20];
...
CALLBACK aCallbackFunc; // aCallbackFunc is a pointer to a function
// returning int
OBNOXIOUSFUNC anObnoxiousFunc; // anObnoxiousFunc is a pointer to a function
// returning a pointer to a 20-element array
// of pointers to int
Попробуйте сделать это с помощью макроса препроцессора.
Это не возможно, не изменяя компилятор. Это вызвано тем, что Дескриптор является абстрактным типом данных, не typeclass.
Если можно выразить то, что Вы хотите сделать с точки зрения C или системных вызовов, Вы могли использовать Внешний функциональный интерфейс (FFI) Haskell. Я начал предлагать использовать mmap, но вообще-то, если задуматься я думаю, что mmap мог бы быть отображением неправильного пути даже при использовании его с анонимной опцией.
можно найти больше информации о Haskell FFI в Wiki haskell.org.
Это не может быть возможно. GHC, по крайней мере, кажется, требует, чтобы дескриптор имел дескриптор файла ОС, который используется для всех, читал/писал/искал операции.
См. /libraries/base/IOBase.lhs
из источников GHC.
Вы можете получать тот же эффект путем включения в список справки ОС: создайте временный файл, подключите дескриптор к нему и затем карту распределения памяти файл для перенаправлений ввода-вывода. Таким образом, весь дескриптор ввод-вывод стал бы видимым в разделе с отображенной памятью.
На самом деле это ошибка в дизайне библиотеки, которая меня тоже раздражает. Я вижу два подхода к тому, чтобы делать то, что вы хотите, ни один из которых не является ужасно привлекательным.
Создайте новый класс типов, сделайте текущий дескриптор его экземпляром, напишите другой экземпляр, чтобы выполнить вещь в памяти-данных, и изменить все ваших программ, которым необходимо использовать это средство. Возможно, это так же просто, как импортировать System.SIO
(или как вы хотите его назвать) вместо System.IO
. Но если вы используете специальные подпрограммы ввода-вывода в библиотеках, таких как Data.ByteString
, там предстоит еще поработать.
Перепишите библиотеки ввода-вывода, чтобы расширить их для поддержки этого. Нетривиально и много работы, но это не будет особенно сложной работой. Однако тогда вы У меня проблема совместимости с системами, в которых нет этой библиотеки.