@[无忌](/space/show?uid=60373)
### 我把带括号和数字(5)的写法编译成汇编(GCC 不开优化 & 不开 C++11):
```cpp
mov esi, OFFSET FLAT:std::fixed(std::ios_base&)
mov edi, OFFSET FLAT:std::cout
call std::basic_ostream<char, std::char_traits<char> >::operator<<(std::ios_base& (*)(std::ios_base&))
mov rbx, rax
mov edi, 5
call std::setprecision(int)
mov esi, eax
mov rdi, rbx
call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::_Setprecision)
movsd xmm0, QWORD PTR [rbp-24]
divsd xmm0, QWORD PTR [rbp-32]
mov rdi, rax
call std::basic_ostream<char, std::char_traits<char> >::operator<<(double)
mov esi, OFFSET FLAT:std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)
mov rdi, rax
call std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))
```
### 再把没有括号和数字的写法编译成汇编:
```cpp
mov esi, OFFSET FLAT:std::fixed(std::ios_base&)
mov edi, OFFSET FLAT:std::cout
call std::basic_ostream<char, std::char_traits<char> >::operator<<(std::ios_base& (*)(std::ios_base&))
mov rdx, rax
mov eax, 1
movzx eax, al
mov esi, eax
mov rdi, rdx
call std::basic_ostream<char, std::char_traits<char> >::operator<<(bool)
movsd xmm0, QWORD PTR [rbp-24]
divsd xmm0, QWORD PTR [rbp-32]
mov rdi, rax
call std::basic_ostream<char, std::char_traits<char> >::operator<<(double)
mov esi, OFFSET FLAT:std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)
mov rdi, rax
call std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))
```
### 发现了两点不同
1. 第一个的第六行有一句 `call std::setprecision(int)`,第二个的第六行是 `movzx eax, al`
2. 第一个的第九行是 `call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::_Setprecision)`;第二个的第九行是 `call std::basic_ostream<char, std::char_traits<char> >::operator<<(bool)`
我想突破点就是在这里了。具体是什么原因,我也不是很清楚。
cppreference 上面说 /*unspecified*/。
by Anguei @ 2018-02-25 19:41:41
@[无忌](/space/show?uid=60373) 我觉得这种东西不如去知乎问问 Milo Yip 等大牛
by Anguei @ 2018-02-25 20:12:10
@[yyfcpp](/space/show?uid=53062) @[无忌](/space/show?uid=60373) 问题远没有这么复杂。
编译选项加一条 -Wall -Wextra
然后再编译这个程序:
```cpp
#include <iostream>
#include <iomanip>
main(){
std::cout<<std::fixed<<std::setprecision<<5.0/3.0;
}
```
就会得到一段警告信息
```plain
xxx.cpp|4|warning: the address of 'std::_Setprecision std::setprecision(int)' will always evaluate as 'true' [-Waddress]|
```
所以,这个程序在输出`5.0/3.0`之前先输出了一个`true`,即`1`。
显然,你说结果大了,是因为你看到的结果是$11.666667$。
而`std::setprecision`在此处并没有起任何效果,精度还是默认的6位。
`std::_Setprecision`是一个`struct`,储存了当前使用的精度,~~cppreference没有细讲,源码不详细,想必实现原理玄学。~~
如需查询当前输出精度,可以参考[这个函数](http://zh.cppreference.com/w/cpp/io/ios_base/precision)
by middle_set @ 2018-02-25 20:19:57
@[hiuseues](/space/show?uid=47842) 哦!我说为什么那个会 call 一个 bool 的输出流,原来是这样!
在 cout 的时候加一句 std::alphano:
```cpp
std::cout << std::boolalpha << std::fixed << std::setprecision << 5.0 / 3.0 << std::endl;
// result: true1.66667
```
by Anguei @ 2018-02-25 21:40:40
@[yyfcpp](/space/show?uid=53062) 额,把 boolalpha 打成 alphano 了,脑抽脑抽
by Anguei @ 2018-02-25 21:41:31