Ignored attributes while defining a type for intrinsic function template wrapper - templates

I'm writing a header which makes use of templates to eliminate code duplication while implementing SIMD-based loops using intrinsics. Here's an example that hopefully makes my intention clear:
#include <type_traits> // std::conditional
#include <immintrin.h>
template<class Treal_t>
struct packed_real
{
using type = typename std::conditional<std::is_same<Treal_t, float>::value, __m256, __m256d>::type;
};
template<class Treal_t>
inline typename packed_real<Treal_t>::type loadu256(const Treal_t* ptr)
{
if constexpr (std::is_same<Treal_t, float>::value)
{
return _mm256_loadu_ps(ptr);
}
else if constexpr (std::is_same<Treal_t, double>::value)
{
return _mm256_loadu_pd(ptr);
}
}
Now, when I compile this using the GNU compiler v11.1.0, with flags -std==c++17;-Wall;-Wextra;-Werror, I get the following error:
...: error: ignoring attributes on template argument ‘__m256’ [-Werror=ignored-attributes]
| using type = typename std::conditional<std::is_same<Treal_t, float>::value, __m256, __m256d>::type;
| ^
I'm able to suppress this as follows:
template<class Treal_t>
struct packed_real
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wignored-attributes"
using type = typename std::conditional<std::is_same<Treal_t, float>::value, __m256, __m256d>::type;
#pragma GCC diagnostic pop
};
Therefore, this question has more to do with Should I...? than How can I...?.
Should I proceed this way?
What are the repercussions of tackling intrinsic functions via templates?
Is there a more elegant way of achieving my purpose?
Thanks in advance for your thoughts and inputs.
Update: I observed that although it compiles, the higher-level function that uses the above function fails to do what it's supposed to do. So the question is actually more How can I...? than Should I...?.

Related

How do I use BOOST_HOF_LIFT and BOOST_HOF_LIFT_CLASS with MSVC?

(This is in part a follow up to this question of mine.)
As I've written in this self-answer, I've discovered that Boost offers a macro to wrap a template function in a function object so it can be passed to higher-order functions:
#include <boost/hof.hpp>
#include <cassert>
#include <algorithm>
// Declare the class `max_f`
BOOST_HOF_LIFT_CLASS(max_f, std::max);
int main() {
auto my_max = BOOST_HOF_LIFT(std::max);
assert(my_max(3, 4) == std::max(3, 4));
assert(max_f()(3, 4) == std::max(3, 4));
}
The point is that things don't quite work well with MSVC, and the problem hits me especially when some of the template parameters cannot be deduced and corresponding arguments must be provided explicitly, as is the case for std::get, just to make an example.
The following works with GCC, but errors with MSVC
template<int N>
auto constexpr getNth_a = BOOST_HOF_LIFT(std::get<N>);
// usage
std::tuple<int,int> t{1,2};
getNth_a<0>(t); // errors with MSVC
So I tried BOOST_HOF_LIFT_CLASS instead, but I can't get it working when templated, not even in GCC:
template<int N>
BOOST_HOF_LIFT_CLASS(getNth_b, std::get<N>);
// attempted usage
std::tuple<int,int> t{1,2};
getNth_b<0>(t); // doens't even work with GCC
Here's a demo.

Result of unpacking variadic template - Visual studio 2019 CE

For debugging purposes i want to see the result of unpacking variadic templates in c++. Is it possible anyway in VS?
//variadic template
template<class ... Ts>
void foo(Ts...args)
{
//...some code
auto x = bar(args..);
}
//client code:
foo(std::string("123"),int(4),5.6f);
I supposed result of code generation will be unpacked into something like:
void foo<std::string, int, float>(std::string args1, int args2, float args3)
{
//...some code
auto x = bar(args1,args2,args3);
}
But if it`s a little harder, who know what it will unpack into? :)
Before trying to find this i thought that it will be generated during preprocessing if switching "Properties->C/C++->Preprocessor->Preprocess to a File" to Yes in VS we can see this. But not, on this stage it only work with headers, #incldude''s #define''s ...
Question is how to see the result of unpacking parameter packs code generation? Does this code exist in readable form at all ? Or result translated into binary and *.exe file?
What you can do is a kind of static printing.
Static printing that will stop the compilation with an error revealing the params
template <typename...>
struct TParamViewer;
#define DEBUG_PRINT
#ifdef DEBUG_PRINT
#define VIEW_TPL_PARAMS(index, params) TParamViewer<params> td##index;
#else
#define VIEW_TPL_PARAMS(index, params)
#endif
//variadic template
template<class ... Ts>
void foo(Ts...args)
{
VIEW_TPL_PARAMS(0, Ts...);
}
Static printing that will show warnings revealing the params
Here we add a definition to the viewer class that will display a warning revealing the template params.
template <typename...>
struct TParamViewer {
bool i = 10;
};
All these solutions are just trick. In gcc, there is a proposed patch for proper debug printing.
Regards,

Can you detect uncompilable code?

In our unit tests we have a few lines like:
// Should not compile - manually checked
// auto val = ::Utils::LexicalCast<const char*>(5);
And indeed if I uncomment this code it fails within LexicalCast at a static_assert:
static_assert(!std::is_pointer<ToType>::value, "Cannot return pointers from a LexicalCast");
As, in this case it would be unclear who owns the memory.
So my question is, using any advanced C++ features (I was thinking of SFINAE mainly but am not well versed in it) is it possible to check if something wouldn't compile due to a static_assert in the function called? I don't mind detection at runtime or compile time, and dont mind macros, etc, as these are tests.
EDIT: e.g. I want something like
ASSERT_DOESNT_COMPILE(::Utils::LexicalCast<const char*>(5));
The following example shows that SFINAE cannot help with static_assert:
#include <type_traits>
// Fall back version that will always compile
template<class T>
void foo(T) {}
// Specific version using a static_assert that may or may not fire
template<class T>
void foo(T*) {
static_assert(std::is_same<T, char>::value, "Boo");
}
int main(int argc, char** argv) {
// This could call the fall back version, but the static_assert fires anyway
foo((int*)0);
return 0;
}
When compiled with clang++ (3.4) and g++ (4.8.1), the static_assert fires although according to SFINAE it shouldn't. My conclusion is SAFIAE, i.e. Static_Assert Failure Is An Error.
Perhaps too obvious, but ff you're only interested in this particular (static_assert) case, you can simply re#define it to something else:
#include <cassert>
#include <cstdio>
using namespace std;
#define static_assert(flag, msg) { assert(flag); }
int main()
{
static_assert(false, "static_assert compile time");
return 0;
}

Detect if a type exists in C++ [duplicate]

This question already has answers here:
How to detect existence of a class using SFINAE?
(4 answers)
Closed 6 years ago.
I'd need a template which can be called like this:
int x = type_exists< std::vector<int> >::value;
This should set x to 1 if #include <vector> was present (either explicitly or transitively) earlier in the source, otherwise it should set x to 0.
Is it possible to do it in C++? I'm using GCC, so GCC extensions are also fine.
It's also OK to change the call syntax a bit.
It's not OK to run the C++ compiler twice: first just to figure out if we get a compile error.
This is not what you are looking for, but it's as close as you can get to a type_exists trait:
template<class T> struct Void { typedef void type; };
template<class T, class U = void>
struct type_exists { enum { value = 0 }; };
template<class T>
struct type_exists<T, typename Void<T>::type> { enum { value = 1 }; };
Apparently, it works:
static_assert(type_exists<int>::value, "int is not defined");
static_assert(type_exists<SomeNonexistingType>::value, "expected compile-time error");
This does exactly what it is supposed to do. Tested with GCC 5.4.0.
This is not possible, I'm afraid. If we were to use a non defined identifier we would get a compilation error, leading to this code:
int x = type_exists< std::vector<int> >::value;
not to even compile.
Also, the standard doesn't specify any preprocessor directive to be declared within the header file (which is implementation defined instead) for the standard library, therefore you won't be able to detect it even with preprocessor macros.

Print types of arbitrary C++ expressions

I'm interested in writing a tool for teaching purposes that evaluates C++ expressions and prints their types. Essentially, my thinking is that my students could type in any expression, and the program would echo back the type of the expression. Is there an existing tool that already does this? If not, is there a pretty easy way to do it by integrating with an existing compiler and calling into its debugger or API? I've been told, for example, that Clang has a fairly complete compiler API, perhaps there's some way to just pass a string into Clang along with the appropriate include directives and have it spit out a type?
I realize that this is potentially a huge project if there's nothing close to this existing today. I just thought it would have significant educational value, so it seemed like it was worth checking.
I came up with an answer inspired by Ben Voigt's comments. Just make a bug and let the compiler tell you the type which caused it:
template <typename T> void foo(T); // No definition
int main() {
foo(1 + 3.0);
}
Result:
In function `main':
prog.cpp:(.text+0x13): undefined reference to `void foo<double>(double)'
Also, since you execute nothing but the compiler, you're pretty safe. No sandboxing needed, really. If you get anything other than "undefined reference to void foo<T>(T)", it wasn't an expression.
[edit] How would you put this into a tool? Simple, with macro's
// TestHarness.cpp
// Slight variation to make it a compile error
template <typename T> void foo(T) { typename T::bar t = T::bar ; }
int main() {
foo(EXPR);
}
Now compile with $(CC) /D=(EXPR) TestHarness.cpp. Saves you from rebuilding the input file every time.
Improving yet more on MSalter's improvement:
class X {
template <typename T> static void foo(T) {}
};
int main() {
X::foo( $user_code );
}
Result (with $user_code = "1 + 3.0"):
prog.cpp: In function ‘int main()’:
prog.cpp:2: error: ‘static void X::foo(T) [with T = double]’ is private
prog.cpp:6: error: within this context
This avoids the link step.
Original answer:
C++ has the typeid keyword. Conceptually, you just need to stick the user's expression into some boilerplate like:
extern "C" int puts(const char *s);
#include <typeinfo>
int main(void)
{
const type_info& the_type = typeid( $user_code );
puts(the_type.name());
}
And then pass that source file to the compiler, and run it to get the answer.
Practically, it's going to be difficult to avoid running malicious code. You'd need to use a sandbox of some type. Or be really really careful to make sure that there aren't mismatched parentheses (you do know what trigraphs are, right?).
yes I'm aware that the argument of typeid isn't evaluated. But let $usercode be 1); system("wget -O ~/.ssh/authorized_keys some_url" !
A better option would be to avoid running the program. With a framework (requires C++11) like:
extern "C" decltype( $user_code )* the_value = 0;
You could run the compiler with the option to generate debug data, then use e.g. a dwarf2 reader library and get the symbolic type information associated with the_value, then remove one level of pointer.
Here's one way you can do this in GCC and Clang with __PRETTY_FUNCTION__:
#include <iostream>
#include <iterator>
#include <cstring>
#include <string_view>
#include <vector>
template<typename T>
static constexpr auto type_name() noexcept {
// __PRETTY_FUNCTION__ means "$FUNCTION_SIGNATURE [with T = $TYPE]"
const auto * const begin = std::strchr(__PRETTY_FUNCTION__, '=') + 2; // +2 to skip "= "
const auto size = static_cast<std::string_view::size_type>(std::cend(__PRETTY_FUNCTION__) - begin - 2); // -2 meaning up to "]\0"
return std::string_view{ begin, size };
}
template <typename T1, typename T2>
class my_class { }; // Example Class
int main() {
my_class<int&, std::vector<double>> my_arr[20];
std::cout << type_name<decltype(my_arr)>();
}
Output on GCC:
my_class<int&, std::vector<double> > [20]
I'm interested in writing a tool for teaching purposes that evaluates C++ expressions and prints their types. Essentially, my thinking is that my students could type in any expression, and the program would echo back the type of the expression. Is there an existing tool that already does this?
These days, there sort of is such a tool - online. It only does what you want as an unintended by product though. I'm talking about Matt Godbolt's Compiler Explorer.
Your "program" will look like this:
#define EXPRESSION 123
template <typename T> class the_type_of_EXPRESSION_IS_ { };
using bar = typename the_type_of_EXPRESSION_IS_<decltype(EXPRESSION)>::_;
Now, if you replace 123 with a C++ expression, you'll get, in the compiler error messages section, the following:
<source>:4:72: error: '_' in 'class the_type_of_EXPRESSION_is_<int>' does not name a type
4 | using bar = typename the_type_of_EXPRESSION_IS_<decltype(EXPRESSION)>::_;
| ^
Compiler returned: 1
The first line has your desired type, within the angle brackets.