Last active
July 1, 2022 00:12
-
-
Save cpmech/ee98a2b9ae2d40e907b03afb32301320 to your computer and use it in GitHub Desktop.
Dangers of using C/C++ lambda functions (NO warnings from the compiler!)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The issue is the "move" inside the
get_x
lambda when using references.