niedziela, 25 stycznia 2015

type_traits: GCC vs Clang

Recently I was writing another article for polish developer journal "Programista" (eng. Programmer). This time I decided to focus on type_traits library - what can we find inside, how it is implemented, and finally - what can we expect in the future (mainly in terms of compile-time reflection).

While writing I was not referring to any particular implementation, but Clang and GCC implementations were opened on the second monitor all the times. I noticed some differences that I'd like to document here.

First things first. Whole post is based on:
The first peculiar difference is that one of the first things that appear in the top of GCC's type_traits are interesting template structures: __and_, __or_, __not_, and so on:
 100   template<typename...>
 101     struct __or_;
 102 
 103   template<>
 104     struct __or_<>
 105     : public false_type
 106     { };
 107 
 108   template<typename _B1>
 109     struct __or_<_B1>
 110     : public _B1
 111     { };

They are used in following fashion:
 709   /// is_unsigned
 710   template<typename _Tp>
 711     struct is_unsigned
 712     : public __and_<is_arithmetic<_Tp>, __not_<is_signed<_Tp>>>::type
 713     { };

At first glance everything looks nice. However you won't find such things in Clang's type_traits implementation. Clang approach is to use standard template mechanisms, like template specialization:
 688 // is_unsigned
 689 
 690 template <class _Tp, bool = is_integral<_Tp>::value>
 691 struct __libcpp_is_unsigned_impl : public integral_constant<bool, _Tp(0) < _Tp(-1)> {};
 692 
 693 template <class _Tp>
 694 struct __libcpp_is_unsigned_impl<_Tp, false> : public false_type {};  // floating point
 695 
 696 template <class _Tp, bool = is_arithmetic<_Tp>::value>
 697 struct __libcpp_is_unsigned : public __libcpp_is_unsigned_impl<_Tp> {};
 698 
 699 template <class _Tp> struct __libcpp_is_unsigned<_Tp, false> : public false_type {};
 700 
 701 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_unsigned : public __libcpp_is_unsigned<_Tp> {};

There's no doubt - GCC's version is more human-friendly. We can read it like it was a book and everything is clear. Reading Clang version is much more harder. Code is bloated with template stuff and there is a lot of kinky helpers.
On the other hand Clang developers use things that are shipped with the C++ compiler. Therefore, at least in theory, compilation should take less time for Clang implementation. It's not that easy to test this, but there's fancy new tool out there - templight. It is a tool that allows us to debug and profile template instances ;)
After some time playing with templight I got following results for simple program that just includes type_traits library, but in two versions: GCC and Clang.

GCCClang
Template instantiations*35
Template memoizations*5945
Maximum memory usage~957kB~2332kB

When we sum instantiations and memoizations it turns out that assumption was right - Clang implementation of type_traits library should be slightly faster. But of course it depends on how compilers are implemented.
Another interesting fact is that during compilation of Clang's type_traits a lot more memory is consumed (comparing to GCC's version).
Both versions of type_traits were compiled using Clang 3.6 (SVN) with templight plugin, so there's no data related to GCC. It may be that for GCC GCC's version of type_traits is better.

The second thing that I've noticed is that Clang's type_traits strive to not rely on compiler built-ins as much as possible while GCC does. Good example here are implementations for std::is_class and std::is_enum.
GCC approach here is to simply use compiler built-ins, like __is_class and __is_enum.
 411   /// is_class
 412   template<typename _Tp>
 413     struct is_class
 414     : public integral_constant<bool, __is_class(_Tp)>
 415     { };
...
 399   /// is_enum
 400   template<typename _Tp>
 401     struct is_enum
 402     : public integral_constant<bool, __is_enum(_Tp)>
 403     { };

 487   { "__is_class",   RID_IS_CLASS,   D_CXXONLY },
 489   { "__is_enum",    RID_IS_ENUM,    D_CXXONLY },

Clang, on contrary, utilizes metaprogramming tricks developed by the community. In case of std::is_class implementation is based on function overloading - the first version of function __is_class_imp::__test accepts pointer to a member and thus will be chosen by the compiler only if the type is a class or union. Therefore second check is needed as well. Simple and brilliant.
 413 namespace __is_class_imp
 414 {
 415 template <class _Tp> char  __test(int _Tp::*);
 416 template <class _Tp> __two __test(...);
 417 }
 418 
 419 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_class
 420     : public integral_constant<bool, sizeof(__is_class_imp::__test<_Tp>(0)) == 1 && !is_union<_Tp>::value> {};


In case of enums there's also interesting bit in Clang implementation:
 500 template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_enum
 501     : public integral_constant<bool, !is_void<_Tp>::value             &&
 502                                      !is_integral<_Tp>::value         &&
 503                                      !is_floating_point<_Tp>::value   &&
 504                                      !is_array<_Tp>::value            &&
 505                                      !is_pointer<_Tp>::value          &&
 506                                      !is_reference<_Tp>::value        &&
 507                                      !is_member_pointer<_Tp>::value   &&
 508                                      !is_union<_Tp>::value            &&
 509                                      !is_class<_Tp>::value            &&
 510                                      !is_function<_Tp>::value         > {};

Voila! No built-ins needed ;)

The last thing I'd like to mention here is std::is_function. GCC's approach here is a bit ridiculous, because it needs a lot of specializations (there are 24 of them so I don't want to include 'em all).
 490   template<typename _Res, typename... _ArgTypes>
 491     struct is_function<_Res(_ArgTypes......) volatile &&>
 492     : public true_type { };
 493 
 494   template<typename _Res, typename... _ArgTypes>
 495     struct is_function<_Res(_ArgTypes...) const volatile>
 496     : public true_type { };
 497 
 498   template<typename _Res, typename... _ArgTypes>
 499     struct is_function<_Res(_ArgTypes...) const volatile &>
 500     : public true_type { };
 501 
 502   template<typename _Res, typename... _ArgTypes>
 503     struct is_function<_Res(_ArgTypes...) const volatile &&>
 504     : public true_type { };

I think that this double template unpacking (or nested unpacking - I don't know how to name this) is good example how to make implementation look like a nightmare. When you have hammer in your hand everything is looking like a nail, isn't it ;)?



* Memoization - "Memoization means we are _not_ instantiating a template because it is already instantiated (but we entered a context where wewould have had to if it was not already instantiated)."

czwartek, 15 stycznia 2015

C++14 template variables in action

As some of you know, in November I conducted a presentation "Metaprogramming in C++: from 70's to C++17" at Code::Dive conference. One of things that I mentioned about C++ templates was what actually can be a template. One of the things that I covered was template variables from C++14. In this post I'd like to present them in action.

However, before I move forward I'd like to see if you can spot the mistake I made during the presentation. I said that following things can be templated in C++. Can you point out the mistake?
  • C++98: class, structure, (member) function
  • C++11: using directive
  • C++14: variable
Do you see it?

The question is tricky. It turns out that since C++98 it was possible to make template union as well. I don't know how about you, but I haven't use union for more than five years from now. I saw it recently as a storage for optional class, though. It's a rare thing, but definitely worth knowing.

Okay, enough off-topic. Let's get back to template variables from C++14. This feature was introduced with N3651 proposal. The proposal argues that in C++ we should have legal mechanisms instead of workarounds like static const variable defined in a class, or value returned from constexpr function.

But what are the use cases of this? The proposal gives us example use case presented below.

1 template <typename T>
2 constexpr T pi = T(3.1415926535897932385);
3 
4 template <typename T>
5 T area_of_circle_with_radius(T r) {
6     return pi<T> * r * r;
7 }

Although this is complete example it was quite hard for me to figure out other use cases in two shakes. The breakthrough came with this commit to Clang's libcxx library. It used this very new feature to make simpler versions of type_traits templates. I hope that following listing is illustrating this well.

 1 namespace ex = std::experimental;
 2 
 3 // ...
 4 {
 5     typedef void T;
 6     static_assert(ex::is_void_v<T>, "");
 7     static_assert(std::is_same<decltype(ex::is_void_v<T>), const bool>::value, "");
 8     static_assert(ex::is_void_v<T> == std::is_void<T>::value, "");
 9 }
10 {
11     typedef int T;
12     static_assert(!ex::is_void_v<T>, "");
13     static_assert(ex::is_void_v<T> == std::is_void<T>::value, "");
14 }
15 {
16     typedef decltype(nullptr) T;
17     static_assert(ex::is_null_pointer_v<T>, "");
18     static_assert(std::is_same<decltype(ex::is_null_pointer_v<T>), const bool>::value, "");
19     static_assert(ex::is_null_pointer_v<T> == std::is_null_pointer<T>::value, "");
20 }
21 // ...

So from this commit onward we are able to write more concise and more readable code in one shot. This nice addition to C++ is practical not only for template variables, but also for making things easier.

piątek, 12 grudnia 2014

Angular.js + CORS + IE11 + invalid URL = "SCRIPT7002: XMLHttpRequest: Network Error 0x7b..."

This time something completely different. I just hope that in future this post might save 2 hours of debugging.

In Nokia I'm the creator of internal search engine (but I actually do this in my leisure time). Something like Google, but only for our intranet. As you may expect it would be an overkill to employ C++ in front-end. Therefore I used Angular.js to do the job. And it does it's job pretty well.

However, recently one user came to me with a complain that he cannot log in into the site. I requested a log from console and got following.

SCRIPT7002: XMLHttpRequest: Network Error 0x7b, The filename, directory name, or volume label syntax is incorrect.

File: *************

Error: Unable to connect to the target server.

   at Anonymous function (https://******/bower_components/angular/angular.min.js:80:237)
   at t (https://******/bower_components/angular/angular.min.js:76:22)
   at Anonymous function (https://******/bower_components/angular/angular.min.js:73:367)
   at J (https://******/bower_components/angular/angular.min.js:100:404)
   [...]

At first glance I thought that this is some kind of bug in IE11 related to missing Origin header in XHR requests (this header is needed if you use CORS (Cross-Origin Resource Sharing)). During debugging this it turned out that the problem is completely different. And quite kinky one.

In some front-end configuration I used following URL.

https:///******

Note that there are three forward slashes. Do you think that IE11 can handle that?



Apparently no. The worst thing is that this part of URL was not present in JavaScript console in the browser.

Removing one forward slash fixed the bug, but 2 hours were wasted anyway.

piątek, 14 listopada 2014

TypeId using constexpr objects

Today we had another interesting conversation at the office. It all started with me explaining to my colleague what static keyword does in respect to free functions. At that time I was wondering whether the same rules apply to variables defined in the scope of translation unit. And... no surprise (luckily not today). However the conversation evolved... and I ended up trying to implement my own compile-time TypeId functionality with no memory footprint (one that vanishes from binary). Please don't ask me how we jumped from static keyword to TypeId ;) It just happened and I'd like to share some thoughts about it with you.

TypeId? Wait.. what exactly is it?
With moderate Google-fu (or having this knowledge before) it takes less than minute to find out typeid operator which is available since C++98. It returns std::type_info which contains some information about type provided as an argument. It is worth noticing that returned value is a lvalue and it lives till the end of your application. What does it mean? Yes, you're right. It all happens in run-time. Since this is not what I wanted to have, this solution was unacceptable.
Even if it would be acceptable - this type information is not available if you don't compile your program with RTTI (Run Time Type Information, -frtti switch for Clang/GCC). It means that there's performance penalty. We have to pay for it, but we'd rather like not to. What do we do, then?



Black magic applied
To solve this problem in compile-time we have to somehow map distinct types to some unique identifiers. I believe there are a lot of approaches over there, but my favorite one is to employ function addresses. Why function addresses? Because every two distinct functions are guaranteed to have different (unique) addresses. In other words two functions can't share one address in memory. Compiler must do this that way, for sure.
However, how can we make use of this fact to create identifier↔type mapping? It's easy - we'll treat addresses of static member functions from class templates as our identifiers. Following snippet illustrates this idea.

1 using TypeId = uintptr_t;
2 
3 template <typename T>
4 struct TypeIdGenerator {
5     static TypeId GetTypeId() {
6         return reinterpret_cast<uintptr_t>(&GetTypeId);
7     }
8 };

So now you may be asking yourself a question about this weird uintptr_t type. Why this particular type? Why not simply integer? It is all because size of a pointer (in this scenario pointer to method) can be of bigger size than other types like int or long. Actually C++ standard does not say a word about size of embedded types, but this is topic for other blog post ;-). The size of unitptr_t is guaranteed to be the same as size of pointers - and that saves us a day.
There's also one more caveat here, though. Unlike POSIX, C++ standard does not support casting pointers to functions to other pointers or scalar types. It is because code may (theoretically) be located in different kind of memory (with different size of words etc.) than data. That is the main reason why I was forced to use reinterpret_cast in above example.

Back to functions
Okay, but still there is one problem with presented code snippet. It leaves trace in assembly (and thus also in binary file):

 1 # g++-4.9.1, -std=c++14 -Os
 2 .LHOTB0:
 3     #        TypeIdGenerator<int>::GetTypeId()
 4     .weak    _ZN15TypeIdGeneratorIiE9GetTypeIdEv
 5     .type    _ZN15TypeIdGeneratorIiE9GetTypeIdEv, @function
 6 _ZN15TypeIdGeneratorIiE9GetTypeIdEv:
 7 .LFB2:
 8     .cfi_startproc
 9     movl    $_ZN15TypeIdGeneratorIiE9GetTypeIdEv, %eax
10     ret
11     .cfi_endproc

To overcome this I tried to use constexpr functions from C++11. I thought it is a good direction because these functions can be both compile-time and run-time. So maybe compile-time version will have some kind of compile-time address that we can use? And maybe this address will not be present in run-time binary? Let's see.

1 using TypeId = uintptr_t;
2 
3 template <typename T>
4 constexpr inline void GetTypeId() {}

Now we can get address of this free function, but unfortunately it still has to have some room in memory. So I was very wrong. However, we already limited implementation of this function to single ret instruction. At least that ;-).

1 _Z9GetTypeIdIiEvv:
2 .LFB2:
3     .cfi_startproc
4     ret
5     .cfi_endproc

Mission failed. I'm sorry. Maybe you have some other ideas how to achieve what I want? Nevertheless I decided to check one last thing - constexpr objects.



Constexpr objects
This was my last resort, but I knew it's not gonna work...

 1 using TypeId = uintptr_t;
 2 
 3 template <typename Type>
 4 struct GetTypeId {
 5     constexpr GetTypeId() {};
 6 };
 7 
 8 int main(void) {
 9     constexpr GetTypeId<int> object;
10     return reinterpret_cast<TypeId>(&object);
11 }

I know it is merely valid, because of returning reference to auto variable. Also, because this variable is auto and not static, identifiers will vary, depending on in which function this constexpr object was created (on the stack). Too bad. However, it gave very interesting output, presented on following assembly snippet.

1 main:
2 .LFB1:
3     .cfi_startproc
4     leaq    -1(%rsp), %rax
5     ret
6     .cfi_endproc

As you can see, there is nothing related to this object variable. At least we don't see this at first glance. GCC is just using the fact that the object is located "above" on the stack. Therefore leaq instruction is used. I was curious whether Clang would behave similarly in this situation:

1 main:                                   # @main
2     .cfi_startproc
3 # BB#0:
4     movl    $_ZZ4mainE6object, %eax
5     retq

In clang the object has some other address which is not relative to the stack. Interesting. It means that Clang will always allocate space in binary to accommodate this constexpr object. Even if it's not static!
I don't know whether this is a bug in Clang or a bug in GCC. If time permits I'll investigate this further.

środa, 12 listopada 2014

Code::Dive conference


Code::dive conference is over. Emotions subsided. In this post I'd like to summarize this conference from my personal point of view.

There were a lot of extremely interesting talks about C++ and not only. Undoubtedly we had one C++ star on the board - Scott Meyers and I'm going to start with it.

Scott gave two talks CPU Caches and why you care and Support for embedded programming in C++11 and C++14. Both of them were meaningful from perspective of a modern C++ engineer. I encourage you to watch these videos!





Besides Scott we had our rising C++ stars from Poland: Andrzej Krzemieński and Bartosz Szurgot. Andrzej was talking about bugs in C++ applications. Bartek's talk was about common pitfalls that occur when we do threading in C++. These two talks were also very inspiring so go watch them as well ;)

I also gave a talk on this conference. My presentation was about Metaprogramming in C++ - from 70's to C++17. As other speaker said - the first time always sucks. And indeed it was my first performance in English. However people are saying that it went quite good so if you have time to waste you can go watch my presentation ;). For the record, slides are here: slideshare.
The last thing I'd like to mention was organisation of this conference. It was first that big conference in Wrocław and I can really say that it went perfectly. Big thanks to organizers!

czwartek, 11 września 2014

Article on Clang internals & Code::Dive conference

Hi, there are two things that I'd like to share with you.

How it's made: Clang C++ compiler

The first one is that I produced one more article for polish developers journal "Programista". This time it is about Clang C++ compiler - how does it work and what's under the bonnet. Unfortunately, it is in Polish, but I promise I'll try to write sth in English soon.

Besides my scribbles you can also find two other interesting articles in current release:

1. Lightweight and portable dispatcher implementation in C++14
This article was written by my workmate Bartosz Szurgot (blog). Not only it describes near-ideal implementation - it also gives some overview on performance issues (useful research, IMHO).

2. C++ Exceptions in details
This in turn is written by Gynvael Coldwind (blog), famous IT security engineer. It is worth reading if you'd like to see how C++ exceptions are really working - in deep details.

Code::Dive

The second thing is my contribution to Code::Dive conference organised by Nokia. The conference is held in Wrocław and I'm going to speak about template metaprogramming in C++. You can find details on the official site.

wtorek, 5 sierpnia 2014

Using static_assert in class-scope

Recently I was working on some presentation (I'm going to post more about this in separate post) and I needed to verify some facts about static_assert in C++11. I decided to look straight in the proposal. Besides information I needed I found that static_assert can be applied in three scopes:
  1. namespace scope
  2. class scope
  3. block scope
I must admit that I only knew about the last option. It took me less than a minute to find out that class scope can be useful in case of my project - compile-time state machine (cfsm).

One example from cfsm is about ATMs. You can find similar code piece in there.
 1 namespace cfsm { // cfsm/Transition.hpp
 2     template <class StateType, StateType From, StateType To> class Transition;
 3 }
 4 
 5 enum class State {
 6     Welcome,
 7     SelectLanguage,
 8     CardError,
 9     // ...
10     PrintConfirmation,
11     Invalid
12 };
13 
14 template <State From, State To> struct AtmTransition : private cfsm::Transition<State, From, To> { };
15 
16 template <> struct AtmTransition<State::Welcome, State::SelectLanguage> { };
17 template <> struct AtmTransition<State::Welcome, State::CardError> { };
18 // ...
19 template <> struct AtmTransition<State::PrintConfirmation, State::Welcome> { };

Goal of this piece is to ensure that only defined transitions are possible. If a programmer makes a mistake, the compiler will yell that there's no specialization for given transition. After all, it is a lot better to catch such errors in compile-time, isn't it?
However, there are some drawbacks of this mechanism - compiler error messages aren't very readable. Compiler just complains about missing specialization. If the user knows what may be the cause it's not a problem. Otherwise he will be forced to go read header files, which are overloaded with templates. What can we do about it?

This is place where class-scope static_assert kicks in. Instead of not providing body for non-specialized transition template we can put one line with some message. It's going to look like following.

1 namespace cfsm { // cfsm/Transition.hpp
2     template <class StateType, StateType From, StateType To> class Transition {
3         static_assert(From == To && From != To, "Illegal transition or missing specialization.");
4     }
5 }

Note: Unfortunately we need to use such weird condition. Otherwise (e.g. in case of simple false) the compiler would do the assertion ad hoc.

There's one more problem to solve. Although custom error message says what the problem is, it doesn't contain enumerator values. This can be split into two separate issues:
  1. Assertion message should be somehow joined by the compiler, basing on multiple constant strings
  2. Enumerator values need to be represented as strings
It turns out that the later issue is addressed by another C++ proposal - N3815, so let's keep our fingers crossed! Anyway, the first problem is not going to be solved at the moment, which is obviously a bad thing.

With this little effort we gained an error message that tells almost everything about the core problem:

static.cpp: In instantiation of ‘class cfsm::Transition<State, (State)0, (State)4>’:
static.cpp:16:40:   required from ‘struct AtmTransition<(State)0, (State)4>’
static.cpp:25:51:   required from here
static.cpp:12:5: error: static assertion failed: Illegal transition or missing specialization.
     static_assert(From == To && From != To, "Illegal transition or missing specialization.");