Search code examples
c++template-meta-programmingboost-hana

Finding the length of a character literals(const char *)


I am not sure about others, but to this day when I want to find out the length of a character literals ex:"somevalue" I use strlen(), now I've been reading a metaprogramming library Hana which I assume would well known in the C++ community, it has some code to deal with string at compile time and then here is a piece of some code

#define BOOST_HANA_STRING(s)                                                \
    (::boost::hana::string_detail::prepare([]{                              \
        struct tmp {                                                        \
            static constexpr decltype(auto) get() { return s; }             \
        };                                                                  \
        return tmp{};                                                       \
    }()))   

basically what it does is

 auto temp = BOOST_HANA_STRING("123");
 constexpr auto sze = sizeof(temp.get())-1; //mov QWORD PTR [rbp-8], 3

Detects the length of the const char * at compile time!! how did it happen? I thought the decltype(auto) kinda did a trick while deducing the return statement, so I wrote like

template<typename constcharstar>
decltype(auto) get(constcharstar ptr) { return ptr; }
constexpr auto sze = sizeof(get("123")); //`mov QWORD PTR [rbp-8], 8`(64-bit arch)

My guess sucks!!, so to figure out what the return s is actually being deduced to, I've used the boost's type_index.hpp

   auto  G = BOOST_HANA_STRING("abcd");
   cout<<boost::typeindex::type_id<decltype(G.get())>().raw_name();
   Result : which prints `A21_c`

My intuition says that the const char * is being deduced to an array of 21 char's (I could be wrong though)

Edit : I figured out it is char [21] used pretty_name()

My question is, how it has got deduced to char [21] and why it only works when I wrapped in struct but not in a free function?


Solution

  • Detects the length of the const char* at compile time!! how did it happen?

    Well, it doesn't. It detects the size of a const char[]. You can try it yourself:

    const char hello[] = "world";
    const auto size = sizeof(hello)-1;
    

    Anything else is sugar.

    My question is, how it has got deduced to char [21] [...]?

    In C++, the type of a string literal is array of cont char of size X where X is appropriately chosen.

    Why it only works when I wrapped in struct but not in a free function?

    It's not about free function vs. struct, it's about macro argument vs. function argument. In #define BOOST_HANA_STRING(s), return s; returns a string literal. In decltype(auto) get(constcharstar ptr), return ptr; returns an already decayed const char*.