为什么模板函数中的 strcmp() return 有不同的值?
Why does strcmp() in a template function return a different value?
我正在重读《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()
比较两个字符串和returns0
是否相等,如果str1
大于[则为正值=16=],如果 str1
小于 str2
,则为负值,这就是我在 main()
中调用 strcmp()
.
得到的结果
问题出在模板函数内部调用 strcmp()
的书中示例中,所以当我 运行 程序时,我得到:
输出:
-5
-1
代码中有什么问题?为什么两者对相同的参数给出不同的值?
这是在 strcmp
传递文字参数时应用的编译器优化,即使在 -O0 上也是如此。请参阅此编译器资源管理器 link: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, 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
正如我们所见,对于上面的 b()
,gcc 正在将对 strcmp
的调用优化为 -1
,而它实际上为 [=] 调用 strcmp
17=]。这是有效的行为,因为 strcmp
returns:
Negative value if lhs appears before rhs in lexicographical order.
Zero if lhs and rhs compare equal.
Positive value if lhs appears after rhs in lexicographical order.
-1
为负数。
如果我们打开优化,gcc 将同样优化 a()
。
我正在重读《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()
比较两个字符串和returns0
是否相等,如果str1
大于[则为正值=16=],如果str1
小于str2
,则为负值,这就是我在main()
中调用strcmp()
.问题出在模板函数内部调用
strcmp()
的书中示例中,所以当我 运行 程序时,我得到:
输出:
-5
-1
代码中有什么问题?为什么两者对相同的参数给出不同的值?
这是在 strcmp
传递文字参数时应用的编译器优化,即使在 -O0 上也是如此。请参阅此编译器资源管理器 link: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, 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
正如我们所见,对于上面的 b()
,gcc 正在将对 strcmp
的调用优化为 -1
,而它实际上为 [=] 调用 strcmp
17=]。这是有效的行为,因为 strcmp
returns:
Negative value if lhs appears before rhs in lexicographical order.
Zero if lhs and rhs compare equal.
Positive value if lhs appears after rhs in lexicographical order.
-1
为负数。
如果我们打开优化,gcc 将同样优化 a()
。