- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So, I get the following error when compiling a class template.
vectors.h(441): error #597: "Vec3<T>::operator Vec3<T>()" will not be called for implicit or explicit conversions
The offending line is a casting operator for a 3-component vector class:
operator Vec3()
{ return Vec3<double>(x, y, z); }
Vec3 is templated on the type of the scalar.
Has anyone come across this and is there a list that tabulates these error codes?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Kannan,
I've figured out below test case to help you understand what the issue is:
template <class T> class A { operator A<float> () const { }; // Cast to A<float> }; template <class T> class B { operator B() const { }; // See what is the difference? using B<TYPE> will avoid the warning. What does this mean? cast to type of B, but B is a template and it need to be B<type>. }; /* int main() { A<int> a; A<float> a1=a; B<int> b; B<float> b1=b; // cannot work, gcc: error: conversion from 'B<int>' to non-scalar type 'B<float>' requested } */ $ gcc temp.cpp -c $ icc temp.cpp -c temp.cpp(10): warning #597: "B<T>::operator B<T>() const" will not be called for implicit or explicit conversions operator B() const { }; // See what is the difference? using B<TYPE> will avoid the warning. What does this mean? cast to type of B, but B is a template and it need to be B<type>. ^ $ icc temp.cpp -c -Werror temp.cpp(10): error #597: "B<T>::operator B<T>() const" will not be called for implicit or explicit conversions operator B() const { }; // See what is the difference? using B<TYPE> will avoid the warning. What does this mean? cast to type of B, but B is a template and it need to be B<type>. ^ compilation aborted for temp.cpp (code 2) $
This is a warning, and the warning do make sense, you need to specify the type for the template (though gcc will not warn it, it is still worth a warning). If you comment out the "main" part in above code and try to understand the code (yes, GCC will report the error as I mentioned in the comments), you'll know why I said a warning is better, this is cast operator and in class B, the code cannot be used (I cannot think of any case this code can be called/used.) as you'll never have a datatype as "B" (since B is a template, it will always be B<int>, B<float>, B<xxx> etc.) for you to cast to. ICC will told you this warning correctly (this cast operator will not be called, in fact, it cannot be called in any case in my understanding.)
Now, why it is an error in ICC? I think you have used -Werror, which will force warning as errors. :)
Hope it is clear and helpful!
Thanks,
Shenghong
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Shengong
Thanks, I understand what you're saying and you're right, I'm treating warnings as errors, so #597 was originally a warning.
Now, on to your example. I made the operators public and compiled it with ICC 16.0 in VS/Windows. This is the compiler output from ICC:
1>ConsoleApplication3.cpp(22): warning #597: "B<T>::operator B<T>() const" will not be called for implicit or explicit conversions
1> operator B() const { };
1> ^
1>
1>ConsoleApplication3.cpp(15): warning #597: "A<T>::operator A<float>() const [with T=float]" will not be called for implicit or explicit conversions
1> operator A<float> () const { };
1> ^
1> detected during instantiation of class "A<T> [with T=float]" at line 47
1>
1>ConsoleApplication3.cpp(50): error : no suitable user-defined conversion from "B<int>" to "B<float>" exists
1> B<float> b1=b;
1> ^
1>
1>ConsoleApplication3.cpp(15): warning #1011: missing return statement at end of non-void function "A<T>::operator A<float> [with T=int]"
1> operator A<float> () const { };
1> ^
1> detected during instantiation of "A<T>::operator A<float>() const [with T=int]" at line 47
1>
1> compilation aborted for ConsoleApplication3.cpp (code 2)
I do understand the error at line 50, this is what you refer to in your post. However, A still produces warning #597 (line 15).
With MSVC 11, I don't get the warnings, only the error about the casting operator for B not working, which is expected. This is the build output from VC
1>ConsoleApplication3.cpp(50): error C2440: 'initializing' : cannot convert from 'B<T>' to 'B<T>'
1> with
1> [
1> T=int
1> ]
1> and
1> [
1> T=float
1> ]
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
I then introduce a third class, C:
template <typename T> class C { T x; public: C() : x(0) {} C(T x_) : x(x_) { } operator C<double> () const { std::cout<<__FUNCTION__; // MS specifc return C(x); } };
And the following calling code in main:
C<int> ic; C<double> dc = ic;
This example produces warning #597 with icc:
1>ConsoleApplication3.cpp(32): warning #597: "C<T>::operator C<double>() const [with T=double]" will not be called for implicit or explicit conversions
1> operator C<double> () const
1> ^
1> detected during instantiation of class "C<T> [with T=double]" at line 53
When I run it, the casting operator is indeed called when the variable dc is created. But there is another problem: the implementation of the operator is an endless recursion!!
MSVC traps this potential recursion:
consoleapplication3.cpp(34): warning C4717: 'C<int>::operator C<double>' : recursive on all control paths, function will cause runtime stack overflow
The fix is to of course specialize the template C before calling the constructor.
template <typename TT> operator C<TT> () const { std::cout<<__FUNCTION__; return C<TT>(x); }
which produces the desired result and no warnings.
Ram
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Ram,
Yes, you are correct, the code may be still invalid, but I just intended to show you why it is a warning of ICC for B (which is very similiar like the case you provided for Vec3, you are not specify the type of the template there) and the warning do make sense.
But you are correct, when I did more testing around, I do see similiar behaviour you mentioned and there seems like be an some issues.
Regarding your C class code, yes, that is more complete and better code.
Below testing are under windows to keep consistent with yours (may be similiar on Linux), and summarize 2 of the warning issues I found (which may need fix/improve from ICC side, I've reported our findings to dev team.) But again, for the original code you posted (or the class B code), this warning may makes sense, as it do will not be called in any case. :)
#include <iostream> #ifdef ISSUE1 template <class T> class A { public: operator A<float> () const { std::cout<<"cast to A<float>"<<std::endl; return A<float>(); }; // Cast to A<float> }; #endif #ifdef ISSUE2 template <class T> class A { public: operator A<float> () const { std::cout<<"cast to A<float>"<<std::endl; return A(); }; // Cast to A<float> }; #endif int main() { A<int> a; A<float> a1=a; // trigger call cast operator } /* Issue1: Reproduce: ================================= On Windows: : cl test.cpp /nologo /EHsc /DISSUE1 test.cpp You are using an Intel supplied intrinsic header file with a third-party compile r. : test.exe cast to A<float> : icl test.cpp /nologo /EHsc /DISSUE1 test.cpp test.cpp(7): warning #597: "A<T>::operator A<float>() const [with T=float]" will not be called for implicit or explicit conversions operator A<float> () const { ^ detected during instantiation of class "A<T> [with T=float]" at line 1 5 : test.exe cast to A<float> : On Linux: $ icc temp.cpp -DISSUE1 temp.cpp(8): warning #597: "A<T>::operator A<float>() const [with T=float]" will not be called for implicit or explicit conversions operator A<float> () const { ^ detected during instantiation of class "A<T> [with T=float]" at line 29 $ ./a.out cast to A<float> $ g++ temp.cpp -DISSUE1 $ ./a.out cast to A<float> $ ================================= Issue: ================================= This warning should not be reported here and in fact, the cast operator will be called correctly from the runing result!!! No warning from MS compiler or GCC compiler. ================================= Issue2: Reproduce: ================================= : icl test.cpp /nologo /EHsc /DISSUE2 test.cpp test.cpp(20): warning #597: "A<T>::operator A<float>() const [with T=float]" wil l not be called for implicit or explicit conversions operator A<float> () const { ^ detected during instantiation of class "A<T> [with T=float]" at line 2 9 : cl test.cpp /nologo /EHsc /DISSUE2 test.cpp You are using an Intel supplied intrinsic header file with a third-party compile r. test.cpp(23) : warning C4717: 'A<int>::operat or A<float>': recursive on all control paths, function will cause runtime stack overflow : run test.exe, it is an endless loop. ================================= Issue: ================================= Wrong/bad warning message from ICC, good warning from MS compiler. On Linux, no any warning with GCC. At least, ICC should remove the waring (this is issue 1 then), if possible, catch the issue like MS compiler. ================================= */
Thanks,
Shenghong

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page