8 Replies Latest reply on Apr 21, 2014 9:36 PM by koval

    Solaris Studio C++ compiler not performing automatic conversion on array arguments

    koval

      I try to compile clang libraries with Solaris Studio C++ compiler.

      Errors occur when processing APInt class.

       

      I have isolated the error:

      template<typename T>
      struct array_ref {
          template<unsigned N>
          array_ref(const T(&)[N]) {}
      };
      
      struct ap_int {
          ap_int(array_ref<int>) {}
      };
      
      int main()
      {
          int array[2] = { 0, 1 };
          ap_int k(array);
          return 0;
      }
      

      This leads to

      line 14: Error: Cannot use int[2] to initialize ap_int

       

      I removed const qualifier from array_ref constructor:

      template<typename T>
      struct array_ref {
          template<unsigned N>
          array_ref(T(&)[N]) {}
      };
      
      struct ap_int {
          ap_int(array_ref<int>) {}
      };
      
      int main()
      {
          int array[2] = { 0, 1 };
          ap_int k(array);
          return 0;
      }
      

      Now the error changes:

      line 14: Error: Formal argument 1 of type array_ref<int> int call to ap_int::ap_int(array_ref<int>) is being passed int*

       

      Let's go further. In the first version (with const) the code below (name it INIT for reference) produces error

      array_ref<int> aref(array);
      

      Error: Cannot use int[2] to initialize array_ref<int>

       

      Without const-qualifier in constructor the above compiles fine.

       

      There is a way to accept a const array as an argument but that requires SFINAE trick:

      template<typename E, typename A>
      struct array_t {};
      
      template<typename E, unsigned N>
      struct array_t<E, E[N]> {
          typedef E* type;
      };
      
      template<typename T>
      struct array_ref {
          template<typename Arr>
          array_ref(const Arr&, typename array_t<T, Arr>::type = 0) {}
      };
      

       

      Now INIT compiles without errors but automatic conversion (initializing ap_int with array) still does not work:

      Error: Formal argument 1 of type array_ref<int> int call to ap_int::ap_int(array_ref<int>) is being passed int*

       

      The only way is to add a constructor with array in ap_int class but this is only a workaround - there is obviously a bug in the compiler.

       

      Tested with:

      • Sun Studio 10 (CC: Sun C++ 5.7 2005/01/07)
      • Sun Studio 11 (CC: Sun C++ 5.8 Patch 121017-10 2007/02/21)
      • Sun Studio 12 (CC: Sun C++ 5.9 SunOS_sparc Patch 123863-01 2007/07/25)
      • Solaris Studio 12.3 (CC: Sun C++ 5.12 SunOS_sparc 2011/11/16).

      All versions give same errors

      I wonder how the next release (12.4) will handle this case