These are chat archives for boostorg/hana

16th
Jan 2016
Jason Rice
@ricejasonf
Jan 16 2016 00:20
I've read in places that it is best practice to not pass primitive types by const& and instead just pass by value. If that is correct, does that mean the same should be done for empty or near empty types like hana::type?
http://stackoverflow.com/questions/10770410/reasons-to-not-pass-simple-types-by-reference?lq=1
Jason Rice
@ricejasonf
Jan 16 2016 00:30
If I use const& it allocates 8 bytes instead of 1
Jason Rice
@ricejasonf
Jan 16 2016 03:41
Sorry, please disregard all of that. It appears to be pretty trivial. (though unpacking a tuple of 100 types does call alloc align 8 100 times, but there is not noticeable difference)
Louis Dionne
@ldionne
Jan 16 2016 19:49
Technically, you’re right that it would be better to pass them by value. But when you trip on a expensive-to-copy type, then you really want to pass by const&. So it’s kind of a tradeof. However, I would be tempted to think that empty objects should be easily optimized away. Could be wrong, in which case it might be worth a LLVM bugreport.
Jason Rice
@ricejasonf
Jan 16 2016 20:00
Do you think it should be optimized away even when compiling -O1?
I noticed hana::equal_impl<type_tag, type_tag> uses const&, but I failed to see any difference when I tried benchmarking a bunch of type comparisons.
Jason Rice
@ricejasonf
Jan 16 2016 20:05
or even unpacking a large tuple
Louis Dionne
@ldionne
Jan 16 2016 20:06

Do you think it should be optimized away even when compiling -O1?

Hard to tell without looking at the assembly. I would probably say "no".

I noticed hana::equal_impl<type_tag, type_tag> uses const&, but I failed to see any difference when I tried benchmarking a bunch of type comparisons.

There is one issue with taking by value. Consider:

int main() {
    auto t = hana::type_c<int>; // not constexpr
    constexpr auto result = hana::equal(t, t); // should work, right?
}

If we make a copy of t, then it does not work anymore, because we're reading from a non-constexpr variable inside a constexpr context. So we have to take by const&, and not read what this (runtime) reference points to.

Jason Rice
@ricejasonf
Jan 16 2016 20:14
that does work
Louis Dionne
@ldionne
Jan 16 2016 20:14
I know, but if you change T const& to T in equal_impl<type_tag, type_tag>, it shouldn’t work anymore.
Jason Rice
@ricejasonf
Jan 16 2016 20:14
It appears to be working.
Louis Dionne
@ldionne
Jan 16 2016 20:15
Wai
Wait*
Jason Rice
@ricejasonf
Jan 16 2016 20:16
#include<boost/hana.hpp>

namespace hana = boost::hana;

int main() {
  auto t = hana::type_c<int>;
  constexpr auto result = hana::equal(t, t);
  BOOST_HANA_CONSTANT_ASSERT(result);
}
Louis Dionne
@ldionne
Jan 16 2016 20:18

If you change the definition of equal_impl to

template <>
struct equal_impl<type_tag, type_tag> {
    template <typename T, typename U>
    static constexpr auto apply(basic_type<T>, basic_type<U>)
    { return hana::false_c; }

    template <typename T>
    static constexpr auto apply(basic_type<T>, basic_type<T>)
    { return hana::true_c; }
};

then you get this error:

FAILED: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++   -DBOOST_HANA_CONFIG_ENABLE_DEBUG_MODE -DBOOST_HANA_CONFIG_ENABLE_STRING_UDL -I../include -I/usr/local/include -I../test/_support -Wno-gnu-string-literal-operator-template -ftemplate-backtrace-limit=0 -pedantic -std=c++1y -Qunused-arguments -W -Wall -Wextra -Wwrite-strings -MMD -MT test/CMakeFiles/test.worksheet.dir/worksheet.cpp.o -MF test/CMakeFiles/test.worksheet.dir/worksheet.cpp.o.d -o test/CMakeFiles/test.worksheet.dir/worksheet.cpp.o -c ../test/worksheet.cpp
../test/worksheet.cpp:1204:20: error: constexpr variable 'result' must be initialized by a constant expression
    constexpr auto result = hana::equal(t, t); // should work, right?
                   ^        ~~~~~~~~~~~~~~~~~
../include/boost/hana/equal.hpp:51:29: note: read of non-constexpr variable 't' is not allowed in a constant expression
        return Equal::apply(static_cast<X&&>(x), static_cast<Y&&>(y));
                            ^
../include/boost/hana/equal.hpp:51:29: note: in call to 'basic_type(t)'
../test/worksheet.cpp:1204:29: note: in call to '&equal->operator()(t, t)'
    constexpr auto result = hana::equal(t, t); // should work, right?
                            ^
../test/worksheet.cpp:1203:10: note: declared here
    auto t = hana::type_c<int>; // not constexpr
         ^
1 error generated.
Jason Rice
@ricejasonf
Jan 16 2016 20:21
super weird.. it is not doing that for me
I even changed both copies of hana on my box just to be sure.
Louis Dionne
@ldionne
Jan 16 2016 20:23
Strange, what compiler?
Jason Rice
@ricejasonf
Jan 16 2016 20:24
Though I get why it 'should' fail because it should try to make a copy of a nonconstexpr.
Louis Dionne
@ldionne
Jan 16 2016 20:24
I need to go right away, I’ll brb in ~1 hour.
Jason Rice
@ricejasonf
Jan 16 2016 20:24
cool
clang version 3.8.0 (http://llvm.org/git/clang.git eb6222eaad7aaec5d9ec0ddd8d1f09e506e689bf) (http://llvm.org/git/llvm.git 08bd0b92116468b52776a55e1fb9dcd479c4a42d)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/llvm/bin
Louis Dionne
@ldionne
Jan 16 2016 20:24
Precisely, it’s reading to a place in memory whose content is runtime, so it cannot do so at compiel-time
I’ll check later, but that might be a bug in Clang trunk