简体   繁体   English

为什么 g++ 对两个无符号数使用 jle 而不是 jbe?

[英]Why is g++ using jle instead of jbe for two unsigned numbers?

In a case where I get this error:在我收到此错误的情况下:

error: assuming signed overflow does not occur when simplifying conditional错误:假设简化条件时不会发生有符号溢出

I looked at the assembly and the if() uses:我查看了程序集和if()使用:

 d34:   48 83 fa 01             cmp    $0x1,%rdx
 d38:   7e 54                   jle    d8e <main+0x3ae>

Interestingly enough, %rdx is defined as an unsigned ( std::size_t ) and the number $0x1 is also defined as an unsigned ( 2UL in the original).有趣的是, %rdx被定义为无符号( std::size_t ),数字$0x1也被定义为无符号( 2UL在原始文件中)。 So why would g++ decide to use jle instead of jbe ?那么为什么 g++ 会决定使用jle而不是jbe呢?

Note: Just in case, I tried with if(colons > 1UL) ... and that did not help.注意:以防万一,我尝试了if(colons > 1UL) ...但这没有帮助。 Same error, same results in assembly.同样的错误,同样的组装结果。


C++ code to reproduce the error:重现错误的 C++ 代码:

#include <algorithm>
#include <string>
#include <iostream>

int main(int argc, char * argv[])
{
    std::string const in(argv[1]);
    std::size_t const colons(std::count(in.begin(), in.end(), ':'));
    if(colons >= 2UL)
    {
        std::cerr << "2 or more colons...\n";
    }
    else
    {
        std::cerr << "no or just one colon.\n";
    }

    return 0;
}

Command line used to reproduce the error:用于重现错误的命令行:

g++ -Werror=strict-overflow -std=c++17 -O3 -o a a.cpp

To compile anyway, just don't use the -Werror=strict-overflow option.无论如何都要编译,只是不要使用-Werror=strict-overflow选项。

The complete result (this is a bit of a killer since the std::count() gets overly optimized for speed):完整的结果(这有点像一个杀手,因为std::count()对速度进行了过度优化):

00000000000009e0 <main>:
 9e0:   41 55                   push   %r13
 9e2:   41 54                   push   %r12
 9e4:   55                      push   %rbp
 9e5:   53                      push   %rbx
 9e6:   48 83 ec 38             sub    $0x38,%rsp
 9ea:   4c 8b 66 08             mov    0x8(%rsi),%r12
 9ee:   48 89 e3                mov    %rsp,%rbx
 9f1:   4c 8d 6b 10             lea    0x10(%rbx),%r13
 9f5:   64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
 9fc:   00 00 
 9fe:   48 89 44 24 28          mov    %rax,0x28(%rsp)
 a03:   31 c0                   xor    %eax,%eax
 a05:   4d 85 e4                test   %r12,%r12
 a08:   4c 89 2c 24             mov    %r13,(%rsp)
 a0c:   0f 84 e8 03 00 00       je     dfa <main+0x41a>
 a12:   4c 89 e7                mov    %r12,%rdi
 a15:   e8 16 ff ff ff          callq  930 <strlen@plt>
 a1a:   48 83 f8 0f             cmp    $0xf,%rax
 a1e:   48 89 c5                mov    %rax,%rbp
 a21:   0f 87 7c 03 00 00       ja     da3 <main+0x3c3>
 a27:   48 83 f8 01             cmp    $0x1,%rax
 a2b:   0f 84 4f 03 00 00       je     d80 <main+0x3a0>
 a31:   48 85 c0                test   %rax,%rax
 a34:   0f 85 cc 03 00 00       jne    e06 <main+0x426>
 a3a:   48 8b 04 24             mov    (%rsp),%rax
 a3e:   48 89 6c 24 08          mov    %rbp,0x8(%rsp)
 a43:   c6 04 28 00             movb   $0x0,(%rax,%rbp,1)
 a47:   48 8b 04 24             mov    (%rsp),%rax
 a4b:   48 8b 54 24 08          mov    0x8(%rsp),%rdx
 a50:   48 8d 34 10             lea    (%rax,%rdx,1),%rsi
 a54:   48 39 f0                cmp    %rsi,%rax
 a57:   0f 84 31 03 00 00       je     d8e <main+0x3ae>
 a5d:   48 89 c1                mov    %rax,%rcx
 a60:   49 89 f1                mov    %rsi,%r9
 a63:   48 83 ea 01             sub    $0x1,%rdx
 a67:   48 f7 d9                neg    %rcx
 a6a:   49 29 c1                sub    %rax,%r9
 a6d:   41 ba 12 00 00 00       mov    $0x12,%r10d
 a73:   83 e1 0f                and    $0xf,%ecx
 a76:   48 8d 78 01             lea    0x1(%rax),%rdi
 a7a:   4c 8d 41 0f             lea    0xf(%rcx),%r8
 a7e:   49 83 f8 12             cmp    $0x12,%r8
 a82:   4d 0f 42 c2             cmovb  %r10,%r8
 a86:   4c 39 c2                cmp    %r8,%rdx
 a89:   0f 82 4b 03 00 00       jb     dda <main+0x3fa>
 a8f:   48 85 c9                test   %rcx,%rcx
 a92:   0f 84 52 03 00 00       je     dea <main+0x40a>
 a98:   45 31 d2                xor    %r10d,%r10d
 a9b:   80 38 3a                cmpb   $0x3a,(%rax)
 a9e:   41 0f 94 c2             sete   %r10b
 aa2:   48 83 f9 01             cmp    $0x1,%rcx
 aa6:   0f 84 34 01 00 00       je     be0 <main+0x200>
 aac:   80 78 01 3a             cmpb   $0x3a,0x1(%rax)
 ab0:   75 04                   jne    ab6 <main+0xd6>
 ab2:   49 83 c2 01             add    $0x1,%r10
 ab6:   48 83 f9 02             cmp    $0x2,%rcx
 aba:   48 8d 78 02             lea    0x2(%rax),%rdi
 abe:   0f 84 1c 01 00 00       je     be0 <main+0x200>
 ac4:   80 78 02 3a             cmpb   $0x3a,0x2(%rax)
 ac8:   75 04                   jne    ace <main+0xee>
 aca:   49 83 c2 01             add    $0x1,%r10
 ace:   48 83 f9 03             cmp    $0x3,%rcx
 ad2:   48 8d 78 03             lea    0x3(%rax),%rdi
 ad6:   0f 84 04 01 00 00       je     be0 <main+0x200>
 adc:   80 78 03 3a             cmpb   $0x3a,0x3(%rax)
 ae0:   75 04                   jne    ae6 <main+0x106>
 ae2:   49 83 c2 01             add    $0x1,%r10
 ae6:   48 83 f9 04             cmp    $0x4,%rcx
 aea:   48 8d 78 04             lea    0x4(%rax),%rdi
 aee:   0f 84 ec 00 00 00       je     be0 <main+0x200>
 af4:   80 78 04 3a             cmpb   $0x3a,0x4(%rax)
 af8:   75 04                   jne    afe <main+0x11e>
 afa:   49 83 c2 01             add    $0x1,%r10
 afe:   48 83 f9 05             cmp    $0x5,%rcx
 b02:   48 8d 78 05             lea    0x5(%rax),%rdi
 b06:   0f 84 d4 00 00 00       je     be0 <main+0x200>
 b0c:   80 78 05 3a             cmpb   $0x3a,0x5(%rax)
 b10:   75 04                   jne    b16 <main+0x136>
 b12:   49 83 c2 01             add    $0x1,%r10
 b16:   48 83 f9 06             cmp    $0x6,%rcx
 b1a:   48 8d 78 06             lea    0x6(%rax),%rdi
 b1e:   0f 84 bc 00 00 00       je     be0 <main+0x200>
 b24:   80 78 06 3a             cmpb   $0x3a,0x6(%rax)
 b28:   0f 84 9a 02 00 00       je     dc8 <main+0x3e8>
 b2e:   48 83 f9 07             cmp    $0x7,%rcx
 b32:   48 8d 78 07             lea    0x7(%rax),%rdi
 b36:   0f 84 a4 00 00 00       je     be0 <main+0x200>
 b3c:   80 78 07 3a             cmpb   $0x3a,0x7(%rax)
 b40:   0f 84 8b 02 00 00       je     dd1 <main+0x3f1>
 b46:   48 83 f9 08             cmp    $0x8,%rcx
 b4a:   48 8d 78 08             lea    0x8(%rax),%rdi
 b4e:   0f 84 8c 00 00 00       je     be0 <main+0x200>
 b54:   80 78 08 3a             cmpb   $0x3a,0x8(%rax)
 b58:   75 04                   jne    b5e <main+0x17e>
 b5a:   49 83 c2 01             add    $0x1,%r10
 b5e:   48 83 f9 09             cmp    $0x9,%rcx
 b62:   48 8d 78 09             lea    0x9(%rax),%rdi
 b66:   74 78                   je     be0 <main+0x200>
 b68:   80 78 09 3a             cmpb   $0x3a,0x9(%rax)
 b6c:   75 04                   jne    b72 <main+0x192>
 b6e:   49 83 c2 01             add    $0x1,%r10
 b72:   48 83 f9 0a             cmp    $0xa,%rcx
 b76:   48 8d 78 0a             lea    0xa(%rax),%rdi
 b7a:   74 64                   je     be0 <main+0x200>
 b7c:   80 78 0a 3a             cmpb   $0x3a,0xa(%rax)
 b80:   75 04                   jne    b86 <main+0x1a6>
 b82:   49 83 c2 01             add    $0x1,%r10
 b86:   48 83 f9 0b             cmp    $0xb,%rcx
 b8a:   48 8d 78 0b             lea    0xb(%rax),%rdi
 b8e:   74 50                   je     be0 <main+0x200>
 b90:   80 78 0b 3a             cmpb   $0x3a,0xb(%rax)
 b94:   75 04                   jne    b9a <main+0x1ba>
 b96:   49 83 c2 01             add    $0x1,%r10
 b9a:   48 83 f9 0c             cmp    $0xc,%rcx
 b9e:   48 8d 78 0c             lea    0xc(%rax),%rdi
 ba2:   74 3c                   je     be0 <main+0x200>
 ba4:   80 78 0c 3a             cmpb   $0x3a,0xc(%rax)
 ba8:   75 04                   jne    bae <main+0x1ce>
 baa:   49 83 c2 01             add    $0x1,%r10
 bae:   48 83 f9 0d             cmp    $0xd,%rcx
 bb2:   48 8d 78 0d             lea    0xd(%rax),%rdi
 bb6:   74 28                   je     be0 <main+0x200>
 bb8:   80 78 0d 3a             cmpb   $0x3a,0xd(%rax)
 bbc:   75 04                   jne    bc2 <main+0x1e2>
 bbe:   49 83 c2 01             add    $0x1,%r10
 bc2:   48 83 f9 0f             cmp    $0xf,%rcx
 bc6:   48 8d 78 0e             lea    0xe(%rax),%rdi
 bca:   75 14                   jne    be0 <main+0x200>
 bcc:   80 78 0e 3a             cmpb   $0x3a,0xe(%rax)
 bd0:   0f 84 0b 02 00 00       je     de1 <main+0x401>
 bd6:   48 8d 78 0f             lea    0xf(%rax),%rdi
 bda:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
 be0:   49 29 c9                sub    %rcx,%r9
 be3:   66 45 0f ef c0          pxor   %xmm8,%xmm8
 be8:   66 0f ef e4             pxor   %xmm4,%xmm4
 bec:   4d 89 c8                mov    %r9,%r8
 bef:   66 0f ef db             pxor   %xmm3,%xmm3
 bf3:   48 01 c8                add    %rcx,%rax
 bf6:   66 0f ef d2             pxor   %xmm2,%xmm2
 bfa:   49 c1 e8 04             shr    $0x4,%r8
 bfe:   66 0f 6f 35 5a 04 00    movdqa 0x45a(%rip),%xmm6        # 1060 <_IO_stdin_used+0x70>
 c05:   00 
 c06:   31 c9                   xor    %ecx,%ecx
 c08:   66 0f 6f 2d 60 04 00    movdqa 0x460(%rip),%xmm5        # 1070 <_IO_stdin_used+0x80>
 c0f:   00 
 c10:   66 0f 6f cc             movdqa %xmm4,%xmm1
 c14:   66 44 0f 6f da          movdqa %xmm2,%xmm11
 c19:   66 0f 6f 00             movdqa (%rax),%xmm0
 c1d:   48 83 c1 01             add    $0x1,%rcx
 c21:   48 83 c0 10             add    $0x10,%rax
 c25:   49 39 c8                cmp    %rcx,%r8
 c28:   66 0f 74 c6             pcmpeqb %xmm6,%xmm0
 c2c:   66 0f db c5             pand   %xmm5,%xmm0
 c30:   66 0f 64 c8             pcmpgtb %xmm0,%xmm1
 c34:   66 0f 6f f8             movdqa %xmm0,%xmm7
 c38:   66 0f 60 f9             punpcklbw %xmm1,%xmm7
 c3c:   66 0f 68 c1             punpckhbw %xmm1,%xmm0
 c40:   66 0f 6f cb             movdqa %xmm3,%xmm1
 c44:   66 44 0f 6f d7          movdqa %xmm7,%xmm10
 c49:   66 0f 65 cf             pcmpgtw %xmm7,%xmm1
 c4d:   66 44 0f 6f c8          movdqa %xmm0,%xmm9
 c52:   66 44 0f 61 d1          punpcklwd %xmm1,%xmm10
 c57:   66 0f 69 f9             punpckhwd %xmm1,%xmm7
 c5b:   66 0f 6f cb             movdqa %xmm3,%xmm1
 c5f:   66 0f 65 c8             pcmpgtw %xmm0,%xmm1
 c63:   66 45 0f 66 da          pcmpgtd %xmm10,%xmm11
 c68:   66 44 0f 61 c9          punpcklwd %xmm1,%xmm9
 c6d:   66 0f 69 c1             punpckhwd %xmm1,%xmm0
 c71:   66 41 0f 6f ca          movdqa %xmm10,%xmm1
 c76:   66 45 0f 6a d3          punpckhdq %xmm11,%xmm10
 c7b:   66 41 0f 62 cb          punpckldq %xmm11,%xmm1
 c80:   66 41 0f d4 c8          paddq  %xmm8,%xmm1
 c85:   66 44 0f 6f c2          movdqa %xmm2,%xmm8
 c8a:   66 41 0f d4 ca          paddq  %xmm10,%xmm1
 c8f:   66 44 0f 6f d7          movdqa %xmm7,%xmm10
 c94:   66 44 0f 66 c7          pcmpgtd %xmm7,%xmm8
 c99:   66 41 0f 6a f8          punpckhdq %xmm8,%xmm7
 c9e:   66 45 0f 62 d0          punpckldq %xmm8,%xmm10
 ca3:   66 45 0f 6f c1          movdqa %xmm9,%xmm8
 ca8:   66 41 0f d4 ca          paddq  %xmm10,%xmm1
 cad:   66 0f d4 cf             paddq  %xmm7,%xmm1
 cb1:   66 0f 6f fa             movdqa %xmm2,%xmm7
 cb5:   66 41 0f 66 f9          pcmpgtd %xmm9,%xmm7
 cba:   66 44 0f 62 c7          punpckldq %xmm7,%xmm8
 cbf:   66 44 0f 6a cf          punpckhdq %xmm7,%xmm9
 cc4:   66 0f 6f fa             movdqa %xmm2,%xmm7
 cc8:   66 41 0f d4 c8          paddq  %xmm8,%xmm1
 ccd:   66 0f 66 f8             pcmpgtd %xmm0,%xmm7
 cd1:   66 44 0f 6f c0          movdqa %xmm0,%xmm8
 cd6:   66 41 0f d4 c9          paddq  %xmm9,%xmm1
 cdb:   66 44 0f 62 c7          punpckldq %xmm7,%xmm8
 ce0:   66 0f 6a c7             punpckhdq %xmm7,%xmm0
 ce4:   66 41 0f d4 c8          paddq  %xmm8,%xmm1
 ce9:   66 0f d4 c8             paddq  %xmm0,%xmm1
 ced:   66 44 0f 6f c1          movdqa %xmm1,%xmm8
 cf2:   0f 87 18 ff ff ff       ja     c10 <main+0x230>
 cf8:   66 0f 73 d9 08          psrldq $0x8,%xmm1
 cfd:   4c 89 c9                mov    %r9,%rcx
 d00:   66 41 0f d4 c8          paddq  %xmm8,%xmm1
 d05:   66 48 0f 7e ca          movq   %xmm1,%rdx
 d0a:   48 83 e1 f0             and    $0xfffffffffffffff0,%rcx
 d0e:   48 8d 04 0f             lea    (%rdi,%rcx,1),%rax
 d12:   4c 01 d2                add    %r10,%rdx
 d15:   49 39 c9                cmp    %rcx,%r9
 d18:   74 1a                   je     d34 <main+0x354>
 d1a:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
 d20:   31 c9                   xor    %ecx,%ecx
 d22:   80 38 3a                cmpb   $0x3a,(%rax)
 d25:   0f 94 c1                sete   %cl
 d28:   48 83 c0 01             add    $0x1,%rax
 d2c:   48 01 ca                add    %rcx,%rdx
 d2f:   48 39 c6                cmp    %rax,%rsi
 d32:   75 ec                   jne    d20 <main+0x340>

# Area of interest:
 d34:   48 83 fa 01             cmp    $0x1,%rdx
 d38:   7e 54                   jle    d8e <main+0x3ae>

 d3a:   48 8d 35 e7 02 00 00    lea    0x2e7(%rip),%rsi        # 1028 <_IO_stdin_used+0x38>
 d41:   48 8d 3d d8 12 20 00    lea    0x2012d8(%rip),%rdi        # 202020 <_ZSt4cerr@@GLIBCXX_3.4>
 d48:   e8 33 fc ff ff          callq  980 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
 d4d:   48 8b 3c 24             mov    (%rsp),%rdi
 d51:   48 83 c3 10             add    $0x10,%rbx
 d55:   48 39 df                cmp    %rbx,%rdi
 d58:   74 05                   je     d5f <main+0x37f>
 d5a:   e8 11 fc ff ff          callq  970 <_ZdlPv@plt>
 d5f:   31 c0                   xor    %eax,%eax
 d61:   48 8b 5c 24 28          mov    0x28(%rsp),%rbx
 d66:   64 48 33 1c 25 28 00    xor    %fs:0x28,%rbx
 d6d:   00 00 
 d6f:   0f 85 80 00 00 00       jne    df5 <main+0x415>
 d75:   48 83 c4 38             add    $0x38,%rsp
 d79:   5b                      pop    %rbx
 d7a:   5d                      pop    %rbp
 d7b:   41 5c                   pop    %r12
 d7d:   41 5d                   pop    %r13
 d7f:   c3                      retq   
 d80:   41 0f b6 04 24          movzbl (%r12),%eax
 d85:   88 44 24 10             mov    %al,0x10(%rsp)
 d89:   e9 ac fc ff ff          jmpq   a3a <main+0x5a>
 d8e:   48 8d 35 a8 02 00 00    lea    0x2a8(%rip),%rsi        # 103d <_IO_stdin_used+0x4d>
 d95:   48 8d 3d 84 12 20 00    lea    0x201284(%rip),%rdi        # 202020 <_ZSt4cerr@@GLIBCXX_3.4>
 d9c:   e8 df fb ff ff          callq  980 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
 da1:   eb aa                   jmp    d4d <main+0x36d>
 da3:   48 8d 78 01             lea    0x1(%rax),%rdi
 da7:   e8 e4 fb ff ff          callq  990 <_Znwm@plt>
 dac:   48 89 6c 24 10          mov    %rbp,0x10(%rsp)
 db1:   48 89 04 24             mov    %rax,(%rsp)
 db5:   48 89 ea                mov    %rbp,%rdx
 db8:   4c 89 e6                mov    %r12,%rsi
 dbb:   48 89 c7                mov    %rax,%rdi
 dbe:   e8 8d fb ff ff          callq  950 <memcpy@plt>
 dc3:   e9 72 fc ff ff          jmpq   a3a <main+0x5a>
 dc8:   49 83 c2 01             add    $0x1,%r10
 dcc:   e9 5d fd ff ff          jmpq   b2e <main+0x14e>
 dd1:   49 83 c2 01             add    $0x1,%r10
 dd5:   e9 6c fd ff ff          jmpq   b46 <main+0x166>
 dda:   31 d2                   xor    %edx,%edx
 ddc:   e9 3f ff ff ff          jmpq   d20 <main+0x340>
 de1:   49 83 c2 01             add    $0x1,%r10
 de5:   e9 ec fd ff ff          jmpq   bd6 <main+0x1f6>
 dea:   48 89 c7                mov    %rax,%rdi
 ded:   45 31 d2                xor    %r10d,%r10d
 df0:   e9 eb fd ff ff          jmpq   be0 <main+0x200>
 df5:   e8 a6 fb ff ff          callq  9a0 <__stack_chk_fail@plt>
 dfa:   48 8d 3d f7 01 00 00    lea    0x1f7(%rip),%rdi        # ff8 <_IO_stdin_used+0x8>
 e01:   e8 3a fb ff ff          callq  940 <_ZSt19__throw_logic_errorPKc@plt>
 e06:   4c 89 e8                mov    %r13,%rax
 e09:   eb aa                   jmp    db5 <main+0x3d5>
 e0b:   48 8b 3c 24             mov    (%rsp),%rdi
 e0f:   48 83 c3 10             add    $0x10,%rbx
 e13:   48 89 c5                mov    %rax,%rbp
 e16:   48 39 df                cmp    %rbx,%rdi
 e19:   74 05                   je     e20 <main+0x440>
 e1b:   e8 50 fb ff ff          callq  970 <_ZdlPv@plt>
 e20:   48 89 ef                mov    %rbp,%rdi
 e23:   e8 98 fb ff ff          callq  9c0 <_Unwind_Resume@plt>
 e28:   0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
 e2f:   00 

For those interested, you may fix the issue by using signed numbers as in:对于那些感兴趣的人,您可以通过使用签名数字来解决问题,如下所示:

#include <type_traits>
...
    if(static_cast<std::make_signed_t<decltype(colons)>>(colons) >= 2LL)
...

or wrap the if() statement around #pragma like so:或将if()语句包裹在#pragma周围,如下所示:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-overflow"
    if(colons >= 2LL)
#pragma GCC diagnostic pop

But this is clearly not the question here.但这显然不是这里的问题。

std::count is defined as: https://github.com/gcc-mirror/gcc/blob/16e2427f50c208dfe07d07f18009969502c25dc8/libstdc%2B%2B-v3/include/bits/stl_algo.h#L4045 std::count定义为: https ://github.com/gcc-mirror/gcc/blob/16e2427f50c208dfe07d07f18009969502c25dc8/libstdc%2B%2B-v3/include/bits/stl_algo.h#L4045

  /**
   *  @brief Count the number of copies of a value in a sequence.
   *  @ingroup non_mutating_algorithms
   *  @param  __first  An input iterator.
   *  @param  __last   An input iterator.
   *  @param  __value  The value to be counted.
   *  @return   The number of iterators @c i in the range @p [__first,__last)
   *  for which @c *i == @p __value
  */
  template<typename _InputIterator, typename _Tp>
    _GLIBCXX20_CONSTEXPR
    inline typename iterator_traits<_InputIterator>::difference_type
    count(_InputIterator __first, _InputIterator __last, const _Tp& __value)
    {
      // concept requirements
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
      __glibcxx_function_requires(_EqualOpConcept<
        typename iterator_traits<_InputIterator>::value_type, _Tp>)
      __glibcxx_requires_valid_range(__first, __last);

      return std::__count_if(__first, __last,
                 __gnu_cxx::__ops::__iter_equals_val(__value));
    }

Then https://github.com/gcc-mirror/gcc/blob/16e2427f50c208dfe07d07f18009969502c25dc8/libstdc%2B%2B-v3/include/bits/stl_algobase.h#L2118 :然后https://github.com/gcc-mirror/gcc/blob/16e2427f50c208dfe07d07f18009969502c25dc8/libstdc%2B%2B-v3/include/bits/stl_algobase.h#L2118

  template<typename _InputIterator, typename _Predicate>
    _GLIBCXX20_CONSTEXPR
    typename iterator_traits<_InputIterator>::difference_type
    __count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
    {
      typename iterator_traits<_InputIterator>::difference_type __n = 0;
      for (; __first != __last; ++__first)
    if (__pred(__first))
      ++__n;
      return __n;
    }

__n is iterator_traits<_InputIterator>::difference_type which is ptrdiff_t a signed type. __niterator_traits<_InputIterator>::difference_type ,它是ptrdiff_t一个有符号类型。 Doing ++__n could result in signed type overflow, but that would be undefined behavior.执行++__n可能会导致有符号类型溢出,但这将是未定义的行为。 Ergo, std::count() can't return negative, cause that would be undefined behavior.因此, std::count()不能返回负数,因为那将是未定义的行为。 Because it can't return negative, compiler can use jle , the number can't be negative.因为它不能返回负数,编译器可以使用jle ,数字不能为负数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM