Advertisement
dluciv

C++ compliers optimization

Feb 22nd, 2017
256
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.28 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <utility>
  4.  
  5. /*
  6. Tested with:
  7.  
  8. i686:
  9. clang++ -O4 --std=c++14 msm.cc
  10. clang++ -O0 --std=c++14 msm.cc
  11.  
  12. x86_64:
  13. g++ -O3 --std=c++14 msm.cc
  14. g++ -O0 --std=c++14 msm.cc
  15. g++ -O3 -fno-elide-constructors --std=c++14 msm.cc
  16.  
  17. x86_64:
  18. cl /Ox /EHsc msm.cc
  19. cl     /EHsc msm.cc
  20.  
  21. Move constructors are agressively optimized by CLang++ and G++,
  22. until told -fno-elide-constructors http://stackoverflow.com/a/8758168/539470,
  23. and less agressively with Visual C++. See (1-3) below.
  24. */
  25.  
  26. std::string shorten(std::string s)
  27. {
  28.     return s.size() <= 16 ? s : std::string(s.begin(), s.begin() + 16) + "...";
  29. }
  30.  
  31. class T
  32. {
  33. private:
  34.     const void *tmp;
  35. public:
  36.     std::string s;
  37.  
  38.     explicit T(const std::string& s0):
  39.     tmp(nullptr), s(s0)
  40.     {
  41.         std::cout << "T(const s& s): s = " << shorten(s) << std::endl;
  42.     }
  43.  
  44.     explicit T(std::string&& s0):
  45.     tmp(nullptr), s(s0)
  46.     {
  47.         std::cout << "T(s&& s): s = " << shorten(s) << std::endl;
  48.     }
  49.  
  50.     T(const T& t):
  51.     tmp(nullptr), s(t.s)
  52.     {
  53.         std::cout << "T(const T& t): s = " << shorten(s) << std::endl;
  54.     }
  55.  
  56.     T(T&& t):
  57.     tmp(t.s.c_str()),
  58.     s(std::move(t.s)) // No t from now. If we try to access t.s below, std::string does not move, it reallocates
  59.     {
  60.         const void *cs = s.c_str();
  61.         std::cout << "T(T&& t): s = " << shorten(s) << "; ptrs = " << cs << " <- " << tmp << std::endl;
  62.     }
  63.     virtual ~T()
  64.     {
  65.         std::cout << "~T(): s = " << shorten(s) << std::endl;
  66.     }
  67. };
  68.  
  69. T f1()
  70. {
  71.     T t = T("t within f1");
  72.     std::cout << "f1: t contains: " << t.s << " at " << ((void *)(t.s.c_str())) << std::endl;
  73.     return t;
  74. }
  75.  
  76. int main()
  77. {
  78.     // (1) move constructor called ONLY when compiling with: VC without optimizations and G++/CLang with -fno-elide-constructors
  79.     T t1 = f1();
  80.     std::cout << "t0 contains " << t1.s << " at " << ((void *)(t1.s.c_str())) << std::endl;
  81.  
  82.     // (2) move constructor called ONLY when compiling with: VC (all options) and G++/CLang with -fno-elide-constructors
  83.     T t2 = T(T("t2"));
  84.  
  85.     // (3) move constructor is called ALWAYS (all compilers, all options)
  86.     T t3 = T(std::move(T("t3")));
  87.  
  88.     // test other constructors
  89.     T t5 = T("123");
  90.     T t6 = t5;
  91.  
  92.     return 0;
  93. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement