Безопасно ли переносить макросы преобразования из caml / mlvalues.h, такие как Val_int, Int_val, в некоторые функции? - PullRequest
1 голос
/ 06 августа 2020

Реализую мост от Ocaml к C ++. Насколько я знаю, только функции, привязанные к стороне OCaml с использованием ключевого слова external , должны определяться как функция C (это необходимо для компоновщика). Значит, они должны содержаться в блоке extern "C" { ... }. За исключением этого момента, я могу использовать код C ++ по своему усмотрению (включая использование в функциях, объявленных в блоке ** extern "C" **).

Чтобы улучшить читаемость, я хочу обернуть макросы из "caml /mlvalues.h ", например

namespace Caml { 
  namespace Value {
    int to_int(value x) { return Int_val(x); }
    value of_int(int x) { return Val_int(x); }
    ...
  }
}

, и использовать Caml::Value::to_int и Caml::Value::of_int вместо исходных Int_val и Val_int. Но для меня это выглядит опасно из-за макросов, побитового копирования и областей видимости. Безопасно ли использовать фасад, подобный описанному выше?

Ответы [ 2 ]

1 голос
/ 04 сентября 2020

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

Макросы CAMLparam, с другой стороны, открывают область видимости, которая закрывается макросами CAMLreturn. И досадно, что вам нужно заранее указать количество аргументов для него.

Вы должны переписать их с нуля на C ++, используя шаблоны vardia c и стиль RAII. Поэтому вместо открытия новой области видимости и объявления некоторых скрытых переменных у вас должен быть реальный объект, который регистрирует аргументы с помощью G C в конструкторе и отменяет их регистрацию в деструкторе.

1 голос
/ 06 августа 2020

Я не вижу ничего плохого в ваших обертках для Int_val и Val_int. Обертка для макроса Field должна возвращать l-значение, но в этом нет ничего сложного:

value &field(value *x, int y) { return Field(x, y); }

Я полагаю, что более интересный код будет происходить из оболочки около Is_block, поэтому чтобы сделать его немного более выразительным.

struct block;
block *as_block(value) ...
value &field(block *, int) ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...