微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么模板函数中的strcmp返回不同的值?

如何解决为什么模板函数中的strcmp返回不同的值?

我正在重新阅读“ C ++ Primer,第5版”。在关于模板的第16章中,有一个“模板非类型参数”示例:

template<unsigned N,unsigned M>
int compare(const char (&p1)[N],const char (&p2)[M])
{
    return strcmp(p1,p2);
}

int main()
{

    cout << compare("hi","mom") << endl;
    cout << strcmp("hi","mom") << endl;


    std::cout << "\ndone!\n";
}
  • 我们知道,strcmp()比较两个字符串并返回0相等,如果str1大于str2则返回正值,而返回负数如果str1小于str2的值,这就是我在main()调用strcmp()的结果。

  • 问题出在书籍示例中,该示例在模板函数调用strcmp(),所以当我运行程序时,我得到:

输出

-5
-1

代码中的问题是什么?为什么两个参数都为相同的参数赋予不同的值?

解决方法

这是在strcmp甚至是-O0上传递文字参数时应用的编译器优化。请参见以下编译器资源管理器链接:https://godbolt.org/z/T4EKxr

#include <cstring>

template<unsigned N,unsigned M>
int compare(const char (&p1)[N],const char (&p2)[M])
{
    return strcmp(p1,p2);
}

int a() {
    return compare("hi","mom");
}

int b() {
    return strcmp("hi","mom");
}

生成的程序集:

.LC0:
        .string "mom"
.LC1:
        .string "hi"
a():
        push    rbp
        mov     rbp,rsp
        mov     esi,OFFSET FLAT:.LC0
        mov     edi,OFFSET FLAT:.LC1
        call    int compare<3u,4u>(char const (&) [3u],char const (&) [4u])
        pop     rbp
        ret
b():
        push    rbp
        mov     rbp,rsp
        mov     eax,-1
        pop     rbp
        ret
int compare<3u,char const (&) [4u]):
        push    rbp
        mov     rbp,rsp
        sub     rsp,16
        mov     QWORD PTR [rbp-8],rdi
        mov     QWORD PTR [rbp-16],rsi
        mov     rdx,QWORD PTR [rbp-16]
        mov     rax,QWORD PTR [rbp-8]
        mov     rsi,rdx
        mov     rdi,rax
        call    strcmp
        leave
        ret

我们可以看到,对于上面的b(),gcc正在将对strcmp的调用优化为一个-1,而实际上它为{{1} }。这是有效的行为,因为strcmp返回:

如果lhs以字典顺序出现在rhs之前,则为负值。

如果lhs和rhs比较相等,则为零。

如果lhs按字典顺序在rhs之后出现,则为正值。

strcmp为负。

如果我们启用优化功能,则gcc将同样优化a()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。