Discussions
Categories
- 196.9K All Categories
- 2.2K Data
- 239 Big Data Appliance
- 1.9K Data Science
- 450.4K Databases
- 221.7K General Database Discussions
- 3.8K Java and JavaScript in the Database
- 31 Multilingual Engine
- 550 MySQL Community Space
- 478 NoSQL Database
- 7.9K Oracle Database Express Edition (XE)
- 3K ORDS, SODA & JSON in the Database
- 546 SQLcl
- 4K SQL Developer Data Modeler
- 187K SQL & PL/SQL
- 21.3K SQL Developer
- 295.9K Development
- 17 Developer Projects
- 138 Programming Languages
- 292.6K Development Tools
- 107 DevOps
- 3.1K QA/Testing
- 646K Java
- 28 Java Learning Subscription
- 37K Database Connectivity
- 155 Java Community Process
- 105 Java 25
- 22.1K Java APIs
- 138.1K Java Development Tools
- 165.3K Java EE (Java Enterprise Edition)
- 18 Java Essentials
- 160 Java 8 Questions
- 86K Java Programming
- 80 Java Puzzle Ball
- 65.1K New To Java
- 1.7K Training / Learning / Certification
- 13.8K Java HotSpot Virtual Machine
- 94.3K Java SE
- 13.8K Java Security
- 204 Java User Groups
- 24 JavaScript - Nashorn
- Programs
- 442 LiveLabs
- 38 Workshops
- 10.2K Software
- 6.7K Berkeley DB Family
- 3.5K JHeadstart
- 5.7K Other Languages
- 2.3K Chinese
- 171 Deutsche Oracle Community
- 1.1K Español
- 1.9K Japanese
- 232 Portuguese
Solaris Studio C++ compiler not performing automatic conversion on array arguments

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
Comments
-
Hi,
You can download the 12.4 beta from here:
The code snippet compiles with the 12.4 beta.
Regards,
Darryl. -
We substantially improved our standard compliance for the template code in 12.4.
Previous versions of Studio C++ were indeed somewhat lacking in that area...
regards,
__Fedor.
-
Thanks Darryl,
I tried to find this download through Oracle site but only found a site where 12.4 beta was only available for premium members.
Regards,
Piotr
-
I hope the earlier link enabled you to try out the beta. Let us know if you have any feedback.
Regards,
Darryl. -
I'll give it a try, it is very good news that Solaris C++ supports C++11 at last.
Regarding the earlier versions and Fedor's opinion:
I faced some bugs in template area but most of the time there is an easy workaround. In case of automatic conversion from array arguments lots of manual work is required (adding array overloads for all methods which use array_ref).
Still, I find CC quite a decent compiler wrt. templates, requiring less workarounds than e.g. earlier VC++.
As for the other areas of standard, this is probably the only compiler which puts <cmath>, <cstring> and other <cXXX> headers in std namespace only, without polluting the global namespace.
Also, CC's optimizer is very good, producing faster code than gcc in many cases.
-
Great! Thanks for the comments.
D. -
> Still, I find CC quite a decent compiler wrt. templates, requiring less workarounds than e.g. earlier VC++.
Well, not that much of an achievement... too many compilers around are better with templates than earlier VC++
> the only compiler which puts <cmath>, <cstring> and other <cXXX> headers in std namespace only
Yeah, and that gives us some troubles
Say, Boost has quite a number of bugs when they use standard functions like strcpy from a global namespace.
And as Studio is pretty much the only compiler who fails to compile the code because of this,
people naturally start blaming our compiler...
Well, Boost tends to fix these bugs as we report them, but then they introduce new ones of the same nature.
regards,
__Fedor.
-
I can confirm that automatic conversion from template arguments, both const and non-const works on 12.4, even in c++03 mode.
The only problem I will face in my project is that -std=c++11 cannot be used together with -library=Cstd. We are using a 3-rd party library (binary only) which is only available for libCstd which means we will not be able to use the new standard
I can understand though, that it is not possible to handle two standards with one ABI which is why a different standard library has to be used with C++11.
Another interesting thing:
CC does not allow classes (even POD-like) with assignment operator in unions. This is absolutely correct and standard-compliant in C++03 mode but g++ somehow seems to allow classes with simple types only to be members of unions regardless of the existance of assignment operators.
This "feature" is used in Qt 5 (json library) and LLVM (a number of unions containing types from Endian.h) and breaks (correcly!) compilation under CC. Thus, Boost is not the only one example of taking g++ as a standard instead of reading the language specification