question

61193447 avatar image
0 Votes"
61193447 asked ·

A bug in VS2019 C++20 compiler, operator <=> ?

Here is the test code.

 // test.cpp : 此文件包含 &#34;main&#34; 函数。程序执行将在此处开始并结束。
 //
 #include &lt;compare&gt;
 #include &lt;iostream&gt;
    
 // 2020-03-16, gxqcn 发现编译器 bug: 如写成 const auto cmp{ *--pl &lt;=&gt; *--pr }, 当 0 != cmp 时,指针会多移动一次!
 int main()
 {
     const auto test{ []( auto a, auto b )
     {
         std::cout &lt;&lt; &#34;before compare: a=&#34; &lt;&lt; a &lt;&lt; &#34; b=&#34; &lt;&lt; b &lt;&lt; &#34;\n&#34;;
         const auto cmp{ a++ &lt;=&gt; b++ };
         std::cout &lt;&lt; &#34;after  compare: a=&#34; &lt;&lt; a &lt;&lt; &#34; b=&#34; &lt;&lt; b &lt;&lt; &#34;\n\n&#34;;
    
         // 为了对比检测 std::max() 是否有类似表现,
         std::cout &lt;&lt; &#34;std::max( a++, b++ ) = &#34; &lt;&lt; std::max( a++, b++ ) &lt;&lt; &#34;\n&#34;;
         std::cout &lt;&lt; &#34;after  std::max: a=&#34; &lt;&lt; a &lt;&lt; &#34; b=&#34; &lt;&lt; b &lt;&lt; &#34;\n\n&#34;;
     }};
    
     test( 1, 1 );   // 测试表明:当相等时,表现与预期相符
     test( 1, 2 );   // 测试表明:当不等时,表现与预期不符
    
     std::cout &lt;&lt; &#34;-------------------------\n\n&#34;;
    
     int v1[]{ 1, 2, 3, 4, 5, 6 };
     int v2[]{ 1, 2, 0, 9, 0, 6 };
    
     auto p1{ std::cbegin( v1 ) - 1 };
     auto p2{ std::cbegin( v2 ) - 1 };
    
     std::cout &lt;&lt; &#34;compare: v1{ 1, 2, 3, 4, 5, 6 } &lt;=&gt; v2{ 1, 2, 0, 9, 0, 6 }\n\n&#34;;
    
     for ( auto index{ 0 }; sizeof( v1 ) / sizeof( v1[ 0 ] ) != index; ++index )
     {
         if ( const auto cmp{ *++p1 &lt;=&gt; *++p2 }; 0 != cmp )
         {
             std::cout &lt;&lt; &#34;v1[&#34; &lt;&lt; index &lt;&lt; &#34;] = &#34; &lt;&lt; v1[ index ] &lt;&lt; &#34;; *p1 =&#34; &lt;&lt; *p1 &lt;&lt; &#34;\n&#34;;
             std::cout &lt;&lt; &#34;v2[&#34; &lt;&lt; index &lt;&lt; &#34;] = &#34; &lt;&lt; v2[ index ] &lt;&lt; &#34;; *p2 =&#34; &lt;&lt; *p2 &lt;&lt; &#34;\n&#34;;
    
             if ( 0 &lt; cmp )
             {
                 std::cout &lt;&lt; &#34;\nv1 &gt; v2&#34;;
             }
             else
             {
                 std::cout &lt;&lt; &#34;\nv1 &lt; v2&#34;;
             }
    
             if (( v1[ index ] &lt;=&gt; v2[ index ] ) == cmp )
             {
                 std::cout &lt;&lt; &#34;, it&#39;s right.\n\n&#34;;
             }
             else
             {
                 std::cout &lt;&lt; &#34; ?! it&#39;s wrong!!\n\n&#34;;
             }
    
             break;
         }
     }
 }

This is the result from VS2019

before compare: a=1 b=1
after compare: a=2 b=2

std::max( a++, b++ ) = 2
after std::max: a=3 b=3

before compare: a=1 b=2
after compare: a=3 b=4

std::max( a++, b++ ) = 4
after std::max: a=4 b=5



compare: v1{ 1, 2, 3, 4, 5, 6 } &amp;amp;amp;lt;=&amp;amp;amp;gt; v2{ 1, 2, 0, 9, 0, 6 }

v1[2] = 3; *p1 =4
v2[2] = 0; *p2 =9

v1 &amp;amp;amp;lt; v2 ?! it&amp;amp;amp;#39;s wrong!!

请按任意键继续. . .

This is the result from gcc-10.0

before compare: a=1 b=1
after compare: a=2 b=2

std::max( a++, b++ ) = 2
after std::max: a=3 b=3

before compare: a=1 b=2
after compare: a=2 b=3

std::max( a++, b++ ) = 3
after std::max: a=3 b=4



compare: v1{ 1, 2, 3, 4, 5, 6 } &amp;amp;amp;lt;=&amp;amp;amp;gt; v2{ 1, 2, 0, 9, 0, 6 }

v1[2] = 3; *p1 =3
v2[2] = 0; *p2 =0

v1 &amp;amp;amp;gt; v2, it&amp;amp;amp;#39;s right.

And the same result from clang10.0

So, is it a bug in VS2019 ?

not-supported
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

RoyLi-MSFT avatar image
0 Votes"
RoyLi-MSFT answered ·

Hello,

Welcome to Microsoft Q&A!


Currently, Microsoft Q&A supports the products listed over here: supported topics (more to be added later on).

Your question about Visual Studio is not supported yet now. You could ask about in Visual Studio's FeedBack.


Thank you.


·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

61193447 avatar image
0 Votes"
61193447 answered ·
 // test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
 //
 #include <compare>
 #include <iostream>
    
 // 2020-03-16, gxqcn 发现编译器 bug: 如写成 const auto cmp{ *--pl <=> *--pr }, 当 0 != cmp 时,指针会多移动一次!
 int main()
 {
     const auto test{ []( auto a, auto b )
     {
         std::cout << "before compare: a=" << a << " b=" << b << "\n";
         const auto cmp{ a++ <=> b++ };
         std::cout << "after  compare: a=" << a << " b=" << b << "\n\n";
    
         // 为了对比检测 std::max() 是否有类似表现,
         std::cout << "std::max( a++, b++ ) = " << std::max( a++, b++ ) << "\n";
         std::cout << "after  std::max: a=" << a << " b=" << b << "\n\n";
     }};
    
     test( 1, 1 );   // 测试表明:当相等时,表现与预期相符
     test( 1, 2 );   // 测试表明:当不等时,表现与预期不符
    
     std::cout << "-------------------------\n\n";
    
     int v1[]{ 1, 2, 3, 4, 5, 6 };
     int v2[]{ 1, 2, 0, 9, 0, 6 };
    
     auto p1{ std::cbegin( v1 ) - 1 };
     auto p2{ std::cbegin( v2 ) - 1 };
    
     std::cout << "compare: v1{ 1, 2, 3, 4, 5, 6 } <=> v2{ 1, 2, 0, 9, 0, 6 }\n\n";
    
     for ( auto index{ 0 }; sizeof( v1 ) / sizeof( v1[ 0 ] ) != index; ++index )
     {
         if ( const auto cmp{ *++p1 <=> *++p2 }; 0 != cmp )
         {
             std::cout << "v1[" << index << "] = " << v1[ index ] << "; *p1 =" << *p1 << "\n";
             std::cout << "v2[" << index << "] = " << v2[ index ] << "; *p2 =" << *p2 << "\n";
    
             if ( 0 < cmp )
             {
                 std::cout << "\nv1 > v2";
             }
             else
             {
                 std::cout << "\nv1 < v2";
             }
    
             if (( v1[ index ] <=> v2[ index ] ) == cmp )
             {
                 std::cout << ", it's right.\n\n";
             }
             else
             {
                 std::cout << " ?! it's wrong!!\n\n";
             }
    
             break;
         }
     }
 }
·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.