Last active
August 22, 2023 12:48
-
-
Save marzer/d722a7b498e0777a3df071ca25ce70dd to your computer and use it in GitHub Desktop.
vs_2022_tuple_ref_bug
This file contains hidden or 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
// demonstration of a bug in VS2022 / MSVC 19.38.32919 | |
// | |
// repro steps: | |
// 1. make a C++17 or later project in VS2022 | |
// 2. add the single-header library "soagen.hpp" to it from here: | |
// https://raw.githubusercontent.com/marzer/soagen/ace22525eeff90d0ff9228b78d0045db87c24099/src/soagen/hpp/single/soagen.hpp | |
// 3. add this code file to it | |
// 4. compile + run | |
// 5. observe that line 53 below (ends with "#### BUG") evaluates to the wrong result | |
// 6. inspect the values in the debugger will show the references are corrupted | |
#include <utility> | |
#include <string> | |
#include <tuple> | |
#include <iostream> | |
#include "soagen.hpp" | |
using employees = soagen::table<soagen::table_traits<unsigned long long /* id */, | |
const std::string /* name */, | |
std::tuple<int, int, int> /* dob */, | |
unsigned long /* salary */>>; | |
template <typename Employee> | |
static void print_employee(const Employee& emp) | |
{ | |
std::cout << "{ " // | |
<< emp.get<0>() << ", " // | |
<< emp.get<1>() << ", " // | |
<< "{ " // | |
<< std::get<0>(emp.get<2>()) << ", " // | |
<< std::get<1>(emp.get<2>()) << ", " // | |
<< std::get<2>(emp.get<2>()) // | |
<< " }, " // | |
<< emp.get<3>() // | |
<< " }\n"; | |
} | |
int main() | |
{ | |
std::cout << std::boolalpha; | |
employees e; | |
e.emplace_back(0, "mark gillard", std::tuple{ 16, 3, 1987 }, 50000); | |
e.emplace_back(1, "joe bloggs", std::tuple{ 10, 4, 1980 }, 60000); | |
e.emplace_back(2, "jane doe", std::tuple{ 6, 5, 1970 }, 70000); | |
print_employee(e[0]); | |
print_employee(std::as_const(e)[1]); | |
print_employee(std::move(e)[2]); | |
std::cout << (e[1] == e[1]) << "\n"; | |
std::cout << (e[1] == std::as_const(e)[1]) << "\n"; | |
std::cout << (e[1] == std::move(e)[1]) << "\n"; // #### BUG: 'false' but should be 'true' | |
std::cout << (e[1] == std::move(std::as_const(e))[1]) << "\n"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment