Can Rcpp do automatic bounds checking? - rcpp

In C++, if using vector types from the STL, some compilers such as GCC have compilation options like _GLIBCXX_ASSERTIONS which will force it to add bound checks for vectors in debug builds, so that if I try to access an element at a position longer than the vector, it will result in an error.
RcppArmadillo has a similar debug macro that can be turned on for bounds checking.
Does Rcpp have something similar for classes like Rcpp::NumericVector or Rcpp::IntegerVector?

Yes it does:
> Rcpp::cppFunction("IntegerVector foo(IntegerVector v) { v.at(11) = 42L; \
return v; }")
> foo( 1:10 )
Error in foo(1:10) : Index out of bounds: [index=11; extent=10].
>
You can also consider RcppArmadillo where Armadillo has the checks on by default with ability to disable:
> Rcpp::cppFunction("arma::vec foo(arma::vec v) { v(11) = 42L; \
return v; }", depends="RcppArmadillo")
> foo( 1:10 )
Error in foo(1:10) : Mat::operator(): index out of bounds
>

Related

Checking the size of a user defined string litteral at compile time in C++11

I'm trying to restrict the use of some user defined litteral for string to a given length
Carte operator"" _C (const char* str, std::size_t sz) {
if (sz != 2)
throw runtime_error("Wrong size of string");
return from_string(str);
}
This works perfectly except that since litteral is known at compile time, the size test could be done at that time as well. However the I can't use a static assert here
jeu.cpp:105:17: error: static_assert expression is not an integral constant expression
static_assert(sz == 2, "Wrong size of string");
^~~~~~~
jeu.cpp:105:17: note: read of non-const variable 'sz' is not allowed in a constant expression
jeu.cpp:104:51: note: declared here
Is there a way to check the size of user defined string litteral at compile time in c++11 ?
If not, is it possible with more recent standard of c++ ?
use sizeof(test) to get length.. then you can use static_assert
const char test[] = "blablalba";
static_assert (sizeof(test) == 10);

Make msvc C4706 go away without pragmas

Following code in MSVC generates warning about assignment in conditional expression.
https://godbolt.org/z/i_rwY9
int main()
{
int a;
if ((a = 5)) {
return 1;
}
return a;
}
Note that I tried to use the double () around if since that makes the warning go away with g++, but I do not know how to make it go away in msvc without extracting the assignment from condition.
Is there a way to nudge msvc to figure out that this assignment is intentional?
I know I can use pragmas to disable this warning, but pattern is very common so I would like to get a solution without pragmas if one exists.
The MSVC compiler will give this warning unless you can convince it that you really do know what you're doing. Adding at least one 'real' logical test will achieve this:
int main()
{
int a;
if ((a = 5) != 0) {
return 1;
}
return a;
}
Note that the constant 5 can readily be replaced with any variable or valid expression: adding the explicit != 0 test does nothing to actually change the outcome of the code (and it is unlikely to change the generated assembly).

Initializing a C++11 string with {}

What is the difference between initializing a string with:
std::string testString = "Test";
and
std::string testString{"Test"};
Is this only syntactic sugar thing or there actually are some performance related differences?
The {} initialization syntax is known as the uniform initialization syntax, it has a few key differences, but in your code as is they both do the same thing - construct a std::string object from the string literal "Test"
Initializing an object with an assignment is essentially the same as putting the right hand side in parentheses and constructing the object. For example the below two are the same
T obj = a;
T obj(a);
So you should be asking yourself, what is the difference between constructing a string object the following two ways
std::string{"Test"};
std::string("Test");
And the answer is that both the constructions above are the same and call the same constructor for std::string
For more on uniform initialization see https://softwareengineering.stackexchange.com/questions/133688/is-c11-uniform-initialization-a-replacement-for-the-old-style-syntax
There is no difference in this particular case. But try
std::string s1(1, '0'); // calls string(size_type , char )
std::string s2{1, '0'}; // calls string(std::initializer_list<char> )
assert(s1.length() == 1 && s1[0] == '0');
assert(s2.length() == 2 && s2[0] == '\x1');
or with std::vector
std::vector<int> v1(1); // calls vector(size_type )
std::vector<int> v2{1}; // calls vector(std::initializer_list<int> )
assert(v1.size() == 1 && v1[0] == 0);
assert(v2.size() == 1 && v2[0] == 1);
There is no difference between them.
First declaration is preferred in most projects due to the syntax highlighting.
I found a clear answer in Herb Sutter
https://herbsutter.com/2013/05/09/gotw-1-solution/

Rust: use of partially moved values

In Rust 0.8:
struct TwoStr {
one: ~str,
two: ~str,
}
#[test]
fn test_contents() {
let strs = TwoStr {
one: ~"pillar",
two: ~"post",
};
assert_eq!(strs.one, ~"pillar");
assert_eq!(strs.two, ~"post");
}
The code won't even compile. The rust test thinks there's an error in the second assert_eq:
error: use of partially moved value: strs
It is somewhat counter-intuitive. I mean, whatever effects the first assert_eq may have, it should be well out of the scope when the execution reaches the second assert_eq. Unless of course, it does some spawn behind the scene. Does it?
If not, why this mysterious error? Hopefully there's no fundamental flaws in my understanding of Rust pointers.
In Rust 0.8, assert_eq! is defined as
macro_rules! assert_eq (
($given:expr , $expected:expr) => (
{
let given_val = $given;
let expected_val = $expected;
// check both directions of equality....
if !((given_val == expected_val) && (expected_val == given_val)) {
fail!(\"assertion failed: `(left == right) && (right == \
left)` (left: `%?`, right: `%?`)\", given_val, expected_val);
}
}
)
)
Note here that it moves both arguments into local let-bindings given_val and expected_val. This is what is causing your error.
In current master, this has been fixed. assert_eq! now takes references to the arguments:
macro_rules! assert_eq (
($given:expr , $expected:expr) => (
{
let given_val = &($given);
let expected_val = &($expected);
// check both directions of equality....
if !((*given_val == *expected_val) &&
(*expected_val == *given_val)) {
fail!("assertion failed: `(left == right) && (right == left)` \
(left: `{:?}`, right: `{:?}`)", *given_val, *expected_val)
}
}
)
)
This means that it no longer moves its arguments, which fixes your error.
If you need to stick with rust 0.8, you can change this to using assert!() instead and do the comparison directly, which will avoid the move. But my recommendation is to upgrade to latest master.
It works on Git master. It must be a bug that was fixed after 0.8 was cut. In general, the released versions are not constrained to be particularly stable before release - they're essentially just snapshots.
The definition of the assert_eq! macro, in libsyntax, takes references to the arguments, so the arguments should not be moved and you can use them after you call the macro.
If you do find another bug, try to compile master if you can, or just make a new issue.

Structures having fixed-size Eigen objects as member and containers

I have a structure with a fixed-size Eigen object as member that I want to use as an edge map with Lemon:
struct EdgeStatus
{
Matrix<float,3,4> Data;
…
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
ListGraph::EdgeMap<EdgeStatus> edgeMap(mygraph);
The code compiles fine, but I get a run-time error:
include/Eigen/src/Core/DenseStorage.h:56: Eigen::internal::plain_array<T, Size, MatrixOrArrayOptions, 16>::plain_array()
[with T = float, int Size = 12, int MatrixOrArrayOptions = 0]: Assertion `(reinterpret_cast<size_t>(array) & 0xf) == 0
&& "this assertion is explained here: " "http://eigen.tuxfamily.org/dox-devel/TopicUnalignedArrayAssert.html" " **** READ THIS WEB PAGE !!! ****"' failed.
Aborted
How should I solve this problem? (I have already included the EIGEN_MAKE_ALIGNED_OPERATOR_NEW macro.)
I don't know the LEMON library, but if ListGraph::EdgeMap allows you to specify an allocator, then you have to use our aligned_allocator.
Otherwise you have to give up vectorization for your members as follow:
struct EdgeStatus
{
Matrix<float,3,4, Eigen::DontAlign> Data;
// ...
};

Resources