
What does your code look like that detects void types? I use the following EXPR_IS_VOID macro myself (which is not originally mine, but I think I have modified it from the original after some testing); feel free to pilfer. The double comma operator thingy is intended to work even if the type of ( Expr ) has an overloaded comma operator, but I've found that GCC has issues with this construct, hence the two versions.
Thank you for help. I have tested your code for void detection which GNUC version gives identical results to the one I use (on msvc, g++ and intel): namespace detail {\ struct returns_void_t {}; static ::boost::type_traits::yes_type returns_void(returns_void_t);\ static ::boost::type_traits::no_type returns_void(int);\ } template <typename T> int operator,(const T&, ::detail::returns_void_t); template <typename T> int operator,(const volatile T&, ::detail::returns_void_t); #define RETURNS_VOID_IMPL(Expr)\ sizeof(::boost::type_traits::yes_type)\ ==\ sizeof(::detail::returns_void(((Expr), ::detail::returns_void_t()))) Here are the results (best viewed in fixed size font) of void detection with functions returning various types (int of class X) with various cv qualifiers and by-value or reference: | g++ | g++ |icpc |msvc | return type |4.3.2|4.5.2|10.0 | 10 | |4.3.4|4.5.3|11.1 | | |4.4.4|4.6.0|12.0 | | void | 1 | 1 | 1 | 1 | int | 0 | 0 | 0 | 0 | int const | 0 | 0 | 0 | 0 | int volatile | 1 | 0 | 0 | 0 | int const volatile | 1 | 0 | 0 | 0 | int & | 0 | 0 | 0 | 0 | int const & | 0 | 0 | 0 | 0 | int volatile & | 0 | 0 | 0 | 0 | int const volatile & | 0 | 0 | 0 | 0 | X | 0 | 0 | 0 | 0 | X const | 0 | 0 | 0 | 0 | X volatile | 1 | 1 |fail | 0 | X const volatile | 1 | 1 |fail | 0 | X & | 0 | 0 | 0 | 0 | X const & | 0 | 0 | 0 | 0 | X volatile & | 0 | 0 | 0 | 0 | X const volatile & | 0 | 0 | 0 | 0 | So only msvc gives the right answer, i.e. detects void returning only when void returning. g++ from version 4.5 says that any cv qualifiers for by-value int is ignored which improves the answer for those return types but returning a class by value with volatile qualifiers fails to complile with intel compiler and gives the wrong answer with g++. I wonder why the code gives the right answer withmsvc. I found another issue with g++ (all versions up to 4.6.0) (works fine with msvc 10 and intel 12): although g++ behaves well with fundamental types returned by value, the result of postfix operator++ applied to an int volatile is detected as void! The standard states in 13.6/3 (Built-in operators): "For every pair (T, VQ), where T is an arithmetic type, and VQ is either volatile or empty, there exist candidate operator functions of the form VQ T& operator++(VQ T&); T operator++(VQ T&, int);" That means that for an "int volatile" variable the corresponding built-in operator should be: int operator++(int volatile &, int); and according to the table above this should be correctly detected as returning non-void. Note that prefix operator++ works fine. This is the program that fails (writes true) with g++ (4.5.2 and 4.6.0): #include <iostream> #include <iomanip> #include <boost/type_traits/detail/yes_no_type.hpp> namespace detail {\ struct returns_void_t {}; static ::boost::type_traits::yes_type returns_void(returns_void_t);\ static ::boost::type_traits::no_type returns_void(int);\ } template <typename T> int operator,(const T&, ::detail::returns_void_t); template <typename T> int operator,(const volatile T&, ::detail::returns_void_t); #define RETURNS_VOID(Expr)\ sizeof(::boost::type_traits::yes_type)\ ==\ sizeof(::detail::returns_void(((Expr), ::detail::returns_void_t()))) int main() { int volatile one_int_volatile; std::cout<<std::boolalpha<<"RETURNS_VOID: "<<(RETURNS_VOID((one_int_volatile++)))<<'\n'; return 0; } Frédéric