c++11 - 为什么即使函数调用中没有任何更改,函数也会返回两个不同的值?
问题描述
在第一种情况下,代码返回 -1
#include <iostream>
template <typename T>
int compare( const T &val1, const T &val2){
if(val1 < val2) return -1;
if(val2 < val1) return 1;
return 0;
}
int main(){
std::string v1= "hello", v2 = "world";
std::cout << compare("hello", "world") << std::endl;
}
在第二种情况下,即使方法调用没有变化,代码也会返回 1。
#include <iostream>
template <typename T>
int compare( const T &val1, const T &val2){
if(val1 < val2) return -1;
if(val2 < val1) return 1;
return 0;
}
int main(){
std::cout << compare("hello", "world") << std::endl;
}
我正在使用 g++ 7.4.0。
解决方案
在这两种情况下T
都推断为char [6]
。在比较数组衰减到指向数组第一个元素的指针时 - char*
。所以你正在比较两个指针,结果是不可预测的,因为你不知道这些字符串文字 - “hello”和“world”是如何定位到内存中的 - 它具有较低的地址。
你得到 0 (这应该是不可能的,因为hello和world作为字符串文字不能占用相同的内存)因为这些条件
if(val1 < val2) return -1;
if(val2 > val1) return 1; // condition val1 > val2 was not tested
// return 0
是相同的。应该:
if(val1 < val2) return -1;
if(val1 > val2) return 1;
访问godbolt,看看行的时候生成了什么代码
std::string v1= "hello", v2 = "world";
被评论。
[1] 未注释时,代码为:
.LC0:
.string "hello"
.LC1:
.string "world"
main:
push rbp
mov rbp, rsp
push rbx
[2] 评论时
.LC0:
.string "world"
.LC1:
.string "hello"
main:
push rbp
mov rbp, rsp
mov esi, OFFSET
你现在看到了吗?LC0
并且LC1
是标签内存(一些比较的值),这就是为什么输出是不可预测的,这取决于编译器如何在内存中存储字符串文字,这是第一个。
推荐阅读
- json - 将 JSON 对象中的两个值连接到 Go 中的 map[string]bool
- r - 如何在 R 中找到目录并自动为其设置工作目录路径?
- javascript - 在 Javascript 中移动 firebase 实时数据库子节点的位置
- android - WebView 自动检测链接、电话号码和邮件地址
- ios - 如何通过 UISlider 和 Swift 使用 CIColorControls 更改亮度、对比度和饱和度
- sql - 找出相等的行集
- python - 抓取多个站点以获取类似信息
- ios - Swift 导航栏动画
- javascript - ES15 导入作为另一个库插件的库
- gmail-addons - 不断收到“部署 ID 未与当前项目关联”。发布时