Skip to content

Instantly share code, notes, and snippets.

@cpmech
Last active July 1, 2022 00:12
Show Gist options
  • Save cpmech/ee98a2b9ae2d40e907b03afb32301320 to your computer and use it in GitHub Desktop.
Save cpmech/ee98a2b9ae2d40e907b03afb32301320 to your computer and use it in GitHub Desktop.
Dangers of using C/C++ lambda functions (NO warnings from the compiler!)
#include <functional>
#include <iostream>
#include <vector>
using namespace std;
const size_t NNODE = 3;
void print_x(size_t num_triangle, function<vector<double> const *(size_t, size_t)> get_x) {
for (size_t t = 0; t < num_triangle; t++) {
for (size_t m = 0; m < NNODE; m++) {
auto x = get_x(t, m);
cout << "triangle # " << t << ": x" << m << " = ";
cout << (*x)[0] << "," << (*x)[1] << endl;
}
}
}
int main() {
try {
// [num_triangle][nnode=3][ndim=2]
vector<vector<vector<double>>> triangles = {
{{0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}},
{{1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}}};
// lambda function that returns the coordinates of cell's point i
auto get_x = [&triangles](size_t t, size_t i) {
return &triangles[t][i];
};
// print data
print_x(triangles.size(), get_x);
} catch (char const *msg) {
cout << "ERROR: " << msg << endl;
} catch (...) {
cout << "some error occurred" << endl;
}
return 0;
}
const NNODE: usize = 3;
fn print_x<'a, F>(num_triangle: usize, get_x: F)
where
F: Fn(usize, usize) -> &'a [f64],
{
for t in 0..num_triangle {
for m in 0..NNODE {
let x = get_x(t, m);
println!("triangle # {}: x = {:?}", t, x);
}
}
}
fn main() {
// [num_triangle][nnode=3][ndim=2]
let triangles = vec![
vec![vec![0.0, 0.0], vec![1.0, 0.0], vec![0.0, 1.0]],
vec![vec![1.0, 0.0], vec![1.2, 1.5], vec![0.0, 1.0]],
];
// closure that returns the coordinates of cell's point i
let get_x = |t: usize, m: usize| &triangles[t][m][..];
// print data
print_x(triangles.len(), get_x);
}
#include <functional>
#include <iostream>
#include <vector>
using namespace std;
const size_t NNODE = 3;
void print_x(size_t num_triangle, function<vector<double> const &(size_t, size_t)> get_x) {
for (size_t t = 0; t < num_triangle; t++) {
for (size_t m = 0; m < NNODE; m++) {
auto x = get_x(t, m);
cout << "triangle # " << t << ": x" << m << " = ";
cout << x[0] << "," << x[1] << endl;
}
}
}
int main() {
try {
// [num_triangle][nnode=3][ndim=2]
vector<vector<vector<double>>> triangles = {
{{0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}},
{{1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}}};
// lambda function that returns the coordinates of cell's point i
auto get_x = [&triangles](size_t t, size_t i) {
return triangles[t][i];
};
// print data
print_x(triangles.size(), get_x);
} catch (char const *msg) {
cout << "ERROR: " << msg << endl;
} catch (...) {
cout << "some error occurred" << endl;
}
return 0;
}
@cpmech
Copy link
Author

cpmech commented Jul 1, 2022

The issue is the "move" inside the get_x lambda when using references.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment