Почему возникает исключение из FFI, но в результате остается пустой список слева? - PullRequest
2 голосов
/ 28 мая 2020

Во-первых, у меня под рукой нет простого воспроизводимого примера, поскольку код обращается к механизму MATLAB, который требует лицензии. Тем не менее, возможно, удастся построить аналогичный пример, просто используя C. У меня есть следующий фрагмент теста:

  ei1 :: Either SomeException MAnyArray <- try $ engineGetVar eng foopi
  putStrLn $ assert (isRight ei1) "  Can clearVar once"
  clearVar eng foopi
  ei2 :: Either SomeException MAnyArray <- try $ engineGetVar eng foopi
  putStrLn $ assert (isLeft ei2) $
    " Can't clearVar twice: " <> (show $ lefts [ei2])
  putStrLn "  Finished testClearVar"

Это приводит к выводу:

  Can clearVar once
Error using save
Variable 'foopi' not found.

 Can't clearVar twice: []
  Finished testClearVar

Немного сбивает с толку это выражение, поскольку утверждение кажется успешным (что означает, что ei2 - это значение Left, но при вызове lefts [ei2] значения Left не найдены):

  putStrLn $ assert (isLeft ei2) $
    " Can't clearVar twice: " <> (show $ lefts [ei2])

1 Ответ

4 голосов
/ 28 мая 2020

Если вы внимательно посмотрите документацию assert, вы обнаружите:

Утверждения обычно могут быть включены или выключены с помощью флага компилятора (для GH C утверждения обычно не включены, если оптимизация включается с помощью -O или указывается опция -fignore-asserts). Когда утверждения отключены, первый аргумент assert игнорируется, а второй аргумент возвращается в качестве результата.

Я предполагаю, что это обычный пакет, над которым вы работаете, а не просто файл, который вы компилируются вручную с помощью ghc. По умолчанию cabal компилирует проект с -O, что означает, что ваши assert просто игнорируются. Что вам нужно, так это добавить флаг -O0 или -fno-ignore-asserts. Но я бы рекомендовал просто не полагаться на assert вообще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...