1 Reply Latest reply: Jan 4, 2013 9:25 AM by Steve.Clamage-Oracle RSS

    Error: The operation "+ U::X" is illegal

    982694
      Hi

      % CC -c t.cc
      "t.cc", line 26: Error: The operation "+ U::X" is illegal.
      1 Error(s) detected.

      I get this error when using Sun Studio 12 (but not with Sun Studio 8) when I try to compile below code.

      If line 11 is removed, the code compiles ok on Sun Studio 12

      % cat -n t.cc
      1 namespace U
      2 {
      3 struct X
      4 {
      5 };
      6
      7 struct Y
      8 {
      9 };
      10
      11 const U::Y& operator+( U::Y& );
      12
      13 struct Z
      14 {
      15 void foo();
      16 };
      17
      18 }
      19
      20 const U::X& operator+( U::X& );
      21
      22 void U::Z::foo()
      23 {
      24 U::X x;
      25
      26 +x;
      27
      28 return;
      29 }


      Edited by: 979691 on 03-Jan-2013 03:53

      Edited by: 979691 on 03-Jan-2013 06:28

      Edited by: 979691 on 03-Jan-2013 06:41

      Edited by: 979691 on 03-Jan-2013 07:45
        • 1. Re: Error: The operation "+ U::X" is illegal
          Steve.Clamage-Oracle
          If the code compiled with Studio 8, it was due to a bug in the compiler. The code is not valid, and the Studio 12 compiler correctly reports the error.

          Recall that function overloading occurs within one scope, not across scopes. A name in an inner scope hides the same name in any outer scope. (There are exceptions in some circumstances when looking up the name of a template or namespace.)

          Function U::Z::foo is in namespace U, so when looking up operator+, the one declared in namespace U hides the global operator+. When you remove the declaration of operator+ in namespace U, the one at global scope becomes visible.

          Here are two ways to use the global operator+ in function foo:
          void U::Z::foo()
          {
              // bring global operator into the overloaded set (probably best)
              using ::operator+;
              U::X x;
              +x;
              return;
          }
          void U::Z::foo()
          {
              U::X x;
              ::operator+(x); // call operator explicitly
              return;
          }