#include<iostream>
#include<type_traits>
// Think that another thread reads this array
template<typename T, size_t M>
inline void zero_func(volatile T (&arr)[M]) {
for(auto &i : arr) i = 0;
}
template<typename T, size_t M>
inline void zero_func(volatile T *ptr) {
zero_func(reinterpret_cast<volatile T (&)[M]>(*ptr));
}
template<typename T, size_t M>
inline void compare_types(volatile T (&arr)[M]) {
volatile char a[M] = {0};
volatile char *b = a;
volatile char * volatile c = a;
decltype(a) d;
std::cout << std::boolalpha;
std::cout << "Which type is equivalent to: volatile char a[M]?" << std::endl;
std::cout << "volatile char *b: \t\t" << std::is_same<decltype(a), decltype(b)>::value << std::endl;
std::cout << "volatile char * volatile c: \t" << std::is_same<decltype(a), decltype(c)>::value << std::endl;
std::cout << "decltype(a): \t\t\t" << std::is_same<decltype(a), decltype(d)>::value << std::endl;
// volatile char a[100] and volatile T (&arr)[M] are same types, excluding reference
typedef decltype(arr) T_vol_ref;
typedef typename std::remove_reference<T_vol_ref>::type T_vol;
std::cout << "volatile T (&arr)[M]: \t\t" << std::is_same<decltype(a), T_vol>::value << std::endl;
}
int main() {
char for_zero[100] = {1};
// secure zero
zero_func<char, 100>(for_zero);
std::cout << (unsigned)for_zero[0] << std::endl;
char *for_zero2 = new char[100];
for_zero2[0] = 1;
zero_func<char, 100>(for_zero2);
std::cout << (unsigned)for_zero2[0] << std::endl;
delete for_zero2;
compare_types(for_zero);
return 0;
}