В каком диапазоне caml_hash_varian возвращает значения?

Подраздел " 20.3.6 Полиморфные варианты" описывает, как определить значение полиморфного варианта в C (* Он содержит ошибку: должно бытьcaml_hash_variant вместо того hash_variant)

Я хочу напрямую использовать эти хеш-значения как коды ошибок в C++. Что-то такое

archive.mli:

...
type t = ...
type err = [`File_not_found | `Archive_is_corrupted]
val opena : string -> (t, err) error
... 

archive.ml

...
let () = Callback.register "open archive" opena
...

archive.cpp:

...
const int Error::File_not_found = caml_hash_variant("File_not_found")
const int Error::Archive_is_corrupted = caml_hash_variant("Archive_is_corrupted")

int Archive::open(char* path) {
  static const value* f = nullptr; \
  if (f = nullptr) 
      f = caml_named_value("open archive");

  value result = caml_callback(*f, caml_copy_string(path));
  if (Tag_val(result) == 0) { // Result.Ok
    archive = Field(caml_state, 0);
    return ??????
  } else { // Result.Error
    return Int_val(Field(caml_state, 0));
  }
}
...

Нет проблем с тем, чтобы вернуть код ошибки и сравнить его

if (x.open(path) == Error::Archive_is_corrupted) {
...
}

Но я не знаю, что я могу вернуть как статус ОК. 0? -1?
Имеет ли какое-либо гарантированное значение, которое не может быть возвращеноcaml_hash_variant существовать?

1 ответ

Решение

Непосредственные значения в обычной реализации OCaml имеют установленный младший бит, а вариантный хэш - это немедленное значение. Поэтому, если вы смотрите на вариантные значения хэша в C++, вы можете быть уверены, что значение 0 никогда не будет возвращено caml_hash_variant.

Если вы посмотрите на код, окончательное значение создается либо Val_int(), либо Val_long(). В определениях этих макросов вы увидите, что они гарантируют установку младшего бита.

Я не проводил никакого анализа кода, но значение -1, по крайней мере, внешне возможно как хэш-значение, поскольку его младший бит установлен.

Обновить

Младший бит устанавливается на немедленные значения в качестве маркера для сборщика мусора. Так что это соглашение, которое необходимо строго соблюдать. (IMHO, это один из многих действительно хороших компромиссов в дизайне реализации OCaml.)

Другие вопросы по тегам