Как Rcpp проверяет границы вектора / матрицы?

0

Я экспериментирую с Rcpp, чтобы увидеть, как работает проверка границ:

> cppFunction ('double fun(){NumericVector v(5); return v[-10];}', rebuild=T)
> fun()
[1] 1.782105e-316
> cppFunction ('double fun(){NumericVector v(5); return v[5];}', rebuild=T)
> fun()
[1] 5.323385e-316

> cppFunction ('NumericVector fun(){NumericMatrix v(5, 5); return v(6,_);}', rebuild=T)
> fun()
Error: index out of bounds
> cppFunction ('double fun(){NumericMatrix v(5, 5); return v(6,1);}', rebuild=T)
> fun()
[1] 0

Я не могу понять, как это работает. Я ожидал ошибку "индекс за пределами границ" для всех 4 из них. Что делать, чтобы он всегда работал как для векторов, так и для матриц? Вот несколько подробных результатов компиляции:

Generated R functions 
-------------------------------------------------------

'.sourceCpp_81484_DLLInfo' <- dyn.load('/tmp/RtmprtDNus/sourcecpp_5b065bfe9a2d/sourceCpp_20261.so')

fun <- Rcpp:::sourceCppFunction(function() {}, FALSE, '.sourceCpp_81484_DLLInfo', 'sourceCpp_81484_fun')

rm('.sourceCpp_81484_DLLInfo')

Building shared library
--------------------------------------------------------

DIR: /tmp/RtmprtDNus/sourcecpp_5b065bfe9a2d

/usr/lib/R/bin/R CMD SHLIB -o 'sourceCpp_20261.so' --preclean 'file5b0652a2d520.cpp' 
g++ -I/usr/share/R/include -DNDEBUG    -I"/home/user/R/x86_64-pc-linux-gnu-library/3.0/Rcpp/include" -fpic  -O3 -pipe  -g  -c file5b0652a2d520.cpp -o file5b0652a2d520.o
g++ -shared -o sourceCpp_20261.so file5b0652a2d520.o -L/usr/lib/R/lib -lR

Нужно ли мне модифицировать аргументы -O3 или -DNDEBUG?

  • 1
    Короткая версия: Rcpp не выполняет проверку границ. Если вы индексируете вне границ, вы получаете мусор.
  • 0
    @KevinUshey так, а как насчет "Ошибка: индекс за пределами"?
Показать ещё 4 комментария
Теги:
matrix
rcpp

1 ответ

1
Лучший ответ

Для двух первых примеров нет проверок границ. Оценки оценок дорогие. То, что вы получаете, - это неопределенное поведение. Признаки в этом случае вы получаете мусор, но вы также можете получить segfault.

В третьем примере используйте _ placeholder для извлечения строки. При построении объекта MatrixRow, представляющего концепцию строки, генерируется исключение, потому что такой строки нет. Вы можете рассуждать, что здесь стоит сделать проверку границ, так как она проверяет "всю строку".

Ваш последний пример выглядит как ошибка. вероятно, в Vector :: offset

  • 0
    Как примечание, в Rcpp11 нет проверки границ в 4-м примере, поэтому вы получите неопределенное поведение. Иногда производительность зависит от пользователя, чтобы делать правильные вещи.
  • 1
    Не уверен, что проверка границ по умолчанию отключена. На практике, да, они замедляют работу примерно на 10-20%, но это необходимо учитывать в более широком контексте времени разработки и отладки. Если включение проверки границ по умолчанию позволяет ускорить разработку, это экономит значительное время. Как только пользователь доволен, что его код работает правильно, он может отключить проверку границ.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню