简体   繁体   English

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

[英]Why does strcmp() in a template function return a different value?

I am reading again "C++ Primer, 5th edition".我正在再次阅读“C++ Primer,第 5 版”。 In chapter 16 about templates, there is an example of "template Non-type parameters":在关于模板的第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";
}
  • As we know, strcmp() compares two character strings and returns 0 for equality, a positive value if str1 is greater than str2 , and a negative value if str1 is less than str2 , and this is what I get inside main() calling strcmp() .我们知道, strcmp()比较两个字符串并返回0表示相等,如果str1大于str2str1正值,如果str1小于str2str1负值,这就是我在main()调用strcmp() .

  • The problem is in the book example that calls strcmp() inside the template function, so when I run the program I get:问题出在在模板函数内部调用strcmp()的书示例中,所以当我运行程序时,我得到:

output:输出:

-5
-1

What is the problem in the code?代码中有什么问题? And why are the two giving different values for the same arguments?为什么两者对相同的参数给出不同的值?

This is a compiler optimization applied when strcmp is passed literal parameters, even on -O0.这是在向strcmp传递文字参数时应用的编译器优化,即使在 -O0 上也是如此。 See this compiler explorer link: https://godbolt.org/z/T4EKxr请参阅此编译器资源管理器链接: 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");
}

The generated assembly:生成的程序集:

.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, 4u>(char const (&) [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

As we can see, for b() above, gcc is optimizing the call to strcmp to just a -1 , whereas it actually calls strcmp for a() .正如我们所看到的,对于上面的b() ,gcc 正在优化对strcmp的调用到只是 a -1 ,而它实际上为a()调用了strcmp This is valid behavior, as strcmp returns:这是有效的行为,因为strcmp返回:

Negative value if lhs appears before rhs in lexicographical order.如果 lhs 按字典顺序出现在 rhs 之前,则为负值。

Zero if lhs and rhs compare equal.如果 lhs 和 rhs 比较相等,则为零。

Positive value if lhs appears after rhs in lexicographical order.如果 lhs 按字典顺序出现在 rhs 之后,则为正值。

-1 is negative. -1为负。

If we turn on optimizations, gcc will similarly optimize a() .如果我们打开优化,gcc 将类似地优化a()

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

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