Reply-To:
slp53@pacbell.net
Sam <
sam@email-scan.com> writes:
Stefan Ram writes:
This (barring typos) is from a book by Bjarne:
int main()
{
string from, to; /* get source and target file names */
cin >> from >> to;
ifstream is( from.c_str() ); /* open input stream */
ofstream os( to.c_str() ); /* open output stream */
istream_iterator<string> ii(is); /* make input iterator for stream */
istream_iterator<string> eos; /* input sentinel */
ostream_iterator<string> oo(os,"\n"); /* make out it. for stream */
set<string> b(ii, eos); /* b is a set initialized from input */
copy(b.begin(), b.end(), oo); /* copy buffer to output */ }
So, is this good style not checking the stream states after opening?
What's the purpose of the above example? Looks to me like it's demonstrating >some basic stream operation, so error checking is immaterial. I would think >that there'll be a separate discussion about error checking where this topic >would be discussed.
It's not clear from which book Stefan found this example. It
doesn't work correctly, however:
$ cat a.cpp
#include <string>
#include <fstream>
#include <iostream>
#include <iterator>
#include <set>
using namespace std;
int main()
{
string from, to; /* get source and target file names */
cin >> from >> to;
ifstream is( from.c_str() ); /* open input stream */
ofstream os( to.c_str() ); /* open output stream */
istream_iterator<string> ii(is); /* make input iterator for stream */
istream_iterator<string> eos; /* input sentinel */
ostream_iterator<string> oo(os,"\n"); /* make out it. for stream */
set<string> b(ii, eos); /* b is a set initialized from input */
copy(b.begin(), b.end(), oo); /* copy buffer to output */
}
$ ./a
i.png
j.png
$ ls -l ?.png
-rw-------. 1 scott scott 2413 Mar 27 13:58 i.png
-rw-rw-r--. 1 scott scott 2411 Mar 27 15:27 j.png
The output file is two bytes shorter than the input file.
The generated code, even with -O2 is horrible, terrible, awful.
0000000000400f90 <main>:
400f90: 41 55 push %r13
400f92: bf 00 31 60 00 mov $0x603100,%edi
400f97: 41 54 push %r12
400f99: 55 push %rbp
400f9a: 53 push %rbx
400f9b: 48 81 ec 38 05 00 00 sub $0x538,%rsp
400fa2: 48 8d 74 24 10 lea 0x10(%rsp),%rsi
400fa7: 48 c7 44 24 10 38 32 movq $0x603238,0x10(%rsp)
400fae: 60 00
400fb0: 48 c7 44 24 20 38 32 movq $0x603238,0x20(%rsp)
400fb7: 60 00
400fb9: e8 d2 fe ff ff callq 400e90 <std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)@plt>
400fbe: 48 8d 74 24 20 lea 0x20(%rsp),%rsi
400fc3: 48 89 c7 mov %rax,%rdi
400fc6: e8 c5 fe ff ff callq 400e90 <std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)@plt>
400fcb: 4c 8d a4 24 20 03 00 lea 0x320(%rsp),%r12
400fd2: 00
400fd3: 48 8b 74 24 10 mov 0x10(%rsp),%rsi
400fd8: ba 08 00 00 00 mov $0x8,%edx
400fdd: 4c 89 e7 mov %r12,%rdi
400fe0: e8 2b ff ff ff callq 400f10 <std::basic_ifstream<char, std::char_traits<char> >::basic_ifstream(char const*, std::_Ios_Openmode)@plt>
400fe5: 48 8b 74 24 20 mov 0x20(%rsp),%rsi
400fea: 48 8d bc 24 20 01 00 lea 0x120(%rsp),%rdi
400ff1: 00
400ff2: ba 30 00 00 00 mov $0x30,%edx
400ff7: e8 24 ff ff ff callq 400f20 <std::basic_ofstream<char, std::char_traits<char> >::basic_ofstream(char const*, std::_Ios_Openmode)@plt>
400ffc: 48 8b 84 24 20 03 00 mov 0x320(%rsp),%rax
401003: 00
401004: 4c 89 64 24 30 mov %r12,0x30(%rsp)
401009: 48 c7 44 24 38 38 32 movq $0x603238,0x38(%rsp)
401010: 60 00
401012: 48 8b 40 e8 mov -0x18(%rax),%rax
401016: f6 84 04 40 03 00 00 testb $0x5,0x340(%rsp,%rax,1)
40101d: 05
40101e: 0f 84 6a 02 00 00 je 40128e <main+0x2fe>
401024: c6 44 24 40 00 movb $0x0,0x40(%rsp)
401029: 48 8d bc 24 98 00 00 lea 0x98(%rsp),%rdi
401030: 00
401031: 48 8d 74 24 58 lea 0x58(%rsp),%rsi
401036: 48 c7 44 24 50 00 00 movq $0x0,0x50(%rsp)
40103d: 00 00
40103f: 48 c7 44 24 58 38 32 movq $0x603238,0x58(%rsp)
401046: 60 00
401048: c6 44 24 60 00 movb $0x0,0x60(%rsp)
40104d: 48 c7 84 24 90 00 00 movq $0x0,0x90(%rsp)
401054: 00 00 00 00 00
401059: e8 02 fe ff ff callq 400e60 <std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)@plt>
40105e: 0f b6 44 24 60 movzbl 0x60(%rsp),%eax
401063: 48 8d 7c 24 78 lea 0x78(%rsp),%rdi
401068: 48 8d 74 24 38 lea 0x38(%rsp),%rsi
40106d: 88 84 24 a0 00 00 00 mov %al,0xa0(%rsp)
401074: 48 8b 44 24 30 mov 0x30(%rsp),%rax
401079: 48 89 44 24 70 mov %rax,0x70(%rsp)
40107e: e8 dd fd ff ff callq 400e60 <std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)@plt>
401083: 0f b6 44 24 40 movzbl 0x40(%rsp),%eax
401088: 48 8d b4 24 98 00 00 lea 0x98(%rsp),%rsi
40108f: 00
40108f: 00
401090: 48 8d bc 24 d8 00 00 lea 0xd8(%rsp),%rdi
401097: 00
401098: c7 84 24 f8 00 00 00 movl $0x0,0xf8(%rsp)
40109f: 00 00 00 00
4010a3: 48 c7 84 24 00 01 00 movq $0x0,0x100(%rsp)
4010aa: 00 00 00 00 00
4010af: 48 c7 84 24 18 01 00 movq $0x0,0x118(%rsp)
4010b6: 00 00 00 00 00
4010bb: 88 84 24 80 00 00 00 mov %al,0x80(%rsp)
4010c2: 48 8d 84 24 f8 00 00 lea 0xf8(%rsp),%rax
4010c9: 00
4010ca: 48 89 84 24 08 01 00 mov %rax,0x108(%rsp)
4010d1: 00
4010d2: 48 89 84 24 10 01 00 mov %rax,0x110(%rsp)
4010d9: 00
4010da: 48 8b 84 24 90 00 00 mov 0x90(%rsp),%rax
4010e1: 00
4010e2: 48 89 84 24 d0 00 00 mov %rax,0xd0(%rsp)
4010e9: 00
4010ea: e8 71 fd ff ff callq 400e60 <std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)@plt>
4010ef: 0f b6 84 24 a0 00 00 movzbl 0xa0(%rsp),%eax
4010f6: 00
4010f7: 48 8d 74 24 78 lea 0x78(%rsp),%rsi
4010fc: 48 8d bc 24 b8 00 00 lea 0xb8(%rsp),%rdi
401103: 00
401104: 88 84 24 e0 00 00 00 mov %al,0xe0(%rsp)
40110b: 48 8b 44 24 70 mov 0x70(%rsp),%rax
401110: 48 89 84 24 b0 00 00 mov %rax,0xb0(%rsp)
401117: 00
401118: e8 43 fd ff ff callq 400e60 <std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::string const&)@plt>
40111d: 0f b6 84 24 80 00 00 movzbl 0x80(%rsp),%eax
401124: 00
401125: 48 8d 94 24 d0 00 00 lea 0xd0(%rsp),%rdx
40112c: 00
40112d: 48 8d b4 24 b0 00 00 lea 0xb0(%rsp),%rsi
401134: 00
401135: 48 8d bc 24 f0 00 00 lea 0xf0(%rsp),%rdi
40113c: 00
40113d: 88 84 24 c0 00 00 00 mov %al,0xc0(%rsp)
401144: e8 27 08 00 00 callq 401970 <void std::_Rb_tree<std::string, std::string, std::_Identity<std::string>, std::less<std::string>, std::allocator<std::string> >::_M_insert_unique<std::istream_iterator<std::string, char, std::char_traits<char>, long> >(std::istream_iterator<std::string, char, std::char_traits<char>, long>, std::istream_iterator<std::string, char, std::char_traits<char>, long>)>
401149: 48 8b 84 24 b8 00 00 mov 0xb8(%rsp),%rax
401150: 00
401151: 4c 8d 6c 24 0f lea 0xf(%rsp),%r13
401156: 48 8d ac 24 f8 00 00 lea 0xf8(%rsp),%rbp
40115d: 00
40115e: 4c 89 ee mov %r13,%rsi
401161: 48 8d 78 e8 lea -0x18(%rax),%rdi
401165: e8 a6 fc ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
40116a: 48 8b 84 24 d8 00 00 mov 0xd8(%rsp),%rax
401171: 00
401172: 48 8d b4 24 b0 00 00 lea 0xb0(%rsp),%rsi
401179: 00
40117a: 48 8d 78 e8 lea -0x18(%rax),%rdi
40117e: e8 8d fc ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
401183: 48 8b 44 24 78 mov 0x78(%rsp),%rax
401188: 48 8d b4 24 d0 00 00 lea 0xd0(%rsp),%rsi
40118f: 00
401190: 48 8d 78 e8 lea -0x18(%rax),%rdi
401194: e8 77 fc ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
401199: 48 8b 84 24 98 00 00 mov 0x98(%rsp),%rax
4011a0: 00
4011a1: 48 8d b4 24 d0 00 00 lea 0xd0(%rsp),%rsi
4011a8: 00
4011a9: 48 8d 78 e8 lea -0x18(%rax),%rdi
4011ad: e8 5e fc ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
4011b2: 48 8b 9c 24 08 01 00 mov 0x108(%rsp),%rbx
4011b9: 00
4011ba: 48 39 eb cmp %rbp,%rbx
4011bd: 74 3d je 4011fc <main+0x26c>
4011bf: 90 nop
4011c0: 48 8b 73 20 mov 0x20(%rbx),%rsi
4011c4: 48 8d bc 24 20 01 00 lea 0x120(%rsp),%rdi
4011cb: 00
4011cc: 48 8b 56 e8 mov -0x18(%rsi),%rdx
4011d0: e8 0b fd ff ff callq 400ee0 <std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)@plt>
4011d5: 48 8d bc 24 20 01 00 lea 0x120(%rsp),%rdi
4011dc: 00
4011dd: ba 01 00 00 00 mov $0x1,%edx
4011e2: be b0 1b 40 00 mov $0x401bb0,%esi
4011e7: e8 f4 fc ff ff callq 400ee0 <std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)@plt>
4011ec: 48 89 df mov %rbx,%rdi
4011ef: e8 bc fc ff ff callq 400eb0 <std::_Rb_tree_increment(std::_Rb_tree_node_base const*)@plt>
4011f4: 48 39 e8 cmp %rbp,%rax
4011f7: 48 89 c3 mov %rax,%rbx
4011fa: 75 c4 jne 4011c0 <main+0x230>
4011fc: 48 8b b4 24 00 01 00 mov 0x100(%rsp),%rsi
401203: 00
401204: 48 8d bc 24 f0 00 00 lea 0xf0(%rsp),%rdi
40120b: 00
40120c: e8 1f 03 00 00 callq 401530 <std::_Rb_tree<std::string, std::string, std::_Identity<std::string>, std::less<std::string>, std::allocator<std::string> >::_M_erase(std::_Rb_tree_node<std::string>*)>
401211: 48 8b 44 24 58 mov 0x58(%rsp),%rax
401216: 48 8d b4 24 d0 00 00 lea 0xd0(%rsp),%rsi
40121d: 00
40121e: 48 8d 78 e8 lea -0x18(%rax),%rdi
401222: e8 e9 fb ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
401227: 48 8b 44 24 38 mov 0x38(%rsp),%rax
40122c: 48 8d b4 24 d0 00 00 lea 0xd0(%rsp),%rsi
401233: 00
401234: 48 8d 78 e8 lea -0x18(%rax),%rdi
401238: e8 d3 fb ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
40123d: 48 8d bc 24 20 01 00 lea 0x120(%rsp),%rdi
401244: 00
401245: e8 86 fc ff ff callq 400ed0 <std::basic_ofstream<char, std::char_traits<char> >::~basic_ofstream()@plt>
40124a: 4c 89 e7 mov %r12,%rdi
40124d: e8 6e fc ff ff callq 400ec0 <std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()@plt>
401252: 48 8b 44 24 20 mov 0x20(%rsp),%rax
401257: 48 8d b4 24 d0 00 00 lea 0xd0(%rsp),%rsi
40125e: 00
40125f: 48 8d 78 e8 lea -0x18(%rax),%rdi
401263: e8 a8 fb ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
401268: 48 8b 44 24 10 mov 0x10(%rsp),%rax
40126d: 48 8d b4 24 d0 00 00 lea 0xd0(%rsp),%rsi
401274: 00
401275: 48 8d 78 e8 lea -0x18(%rax),%rdi
401279: e8 92 fb ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
40127e: 48 81 c4 38 05 00 00 add $0x538,%rsp
401285: 31 c0 xor %eax,%eax
401287: 5b pop %rbx
401288: 5d pop %rbp
401289: 41 5c pop %r12
40128b: 41 5d pop %r13
40128d: c3 retq
40128e: 48 8d 74 24 38 lea 0x38(%rsp),%rsi
401293: 4c 89 e7 mov %r12,%rdi
401296: c6 44 24 40 01 movb $0x1,0x40(%rsp)
40129b: e8 f0 fb ff ff callq 400e90 <std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)@plt>
4012a0: 48 8b 54 24 30 mov 0x30(%rsp),%rdx
4012a5: 48 8b 02 mov (%rdx),%rax
4012a8: 48 03 50 e8 add -0x18(%rax),%rdx
4012ac: 31 c0 xor %eax,%eax
4012ae: f6 42 20 05 testb $0x5,0x20(%rdx)
4012b2: 48 0f 44 c2 cmove %rdx,%rax
4012b6: 48 85 c0 test %rax,%rax
4012b9: 0f 95 44 24 40 setne 0x40(%rsp)
4012be: e9 66 fd ff ff jmpq 401029 <main+0x99>
4012c3: 48 89 c3 mov %rax,%rbx
4012c6: 48 8b 44 24 38 mov 0x38(%rsp),%rax
4012cb: 48 8d 74 24 0f lea 0xf(%rsp),%rsi
4012d0: 48 8d 78 e8 lea -0x18(%rax),%rdi
4012d4: e8 37 fb ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
4012d9: 48 8d bc 24 20 01 00 lea 0x120(%rsp),%rdi
4012e0: 00
4012e1: e8 ea fb ff ff callq 400ed0 <std::basic_ofstream<char, std::char_traits<char> >::~basic_ofstream()@plt>
4012e6: 4c 89 e7 mov %r12,%rdi
4012e9: e8 d2 fb ff ff callq 400ec0 <std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()@plt>
4012ee: 48 8b 44 24 20 mov 0x20(%rsp),%rax
4012f3: 48 8d 74 24 0e lea 0xe(%rsp),%rsi
4012f8: 48 8d 78 e8 lea -0x18(%rax),%rdi
4012fc: e8 0f fb ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
401301: 48 8b 44 24 10 mov 0x10(%rsp),%rax
401306: 48 8d 74 24 0e lea 0xe(%rsp),%rsi
40130b: 48 8d 78 e8 lea -0x18(%rax),%rdi
40130f: e8 fc fa ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
401314: 48 89 df mov %rbx,%rdi
401317: e8 64 fc ff ff callq 400f80 <_Unwind_Resume@plt>
40131c: 48 8b b4 24 00 01 00 mov 0x100(%rsp),%rsi
401323: 00
401324: 48 8d bc 24 f0 00 00 lea 0xf0(%rsp),%rdi
40132b: 00
40132c: 48 89 c3 mov %rax,%rbx
40132f: e8 fc 01 00 00 callq 401530 <std::_Rb_tree<std::string, std::string, std::_Identity<std::string>, std::less<std::string>, std::allocator<std::string> >::_M_erase(std::_Rb_tree_node<std::string>*)>
401334: 48 8b 44 24 58 mov 0x58(%rsp),%rax
401339: 4c 89 ee mov %r13,%rsi
40133c: 48 8d 78 e8 lea -0x18(%rax),%rdi
401340: e8 cb fa ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
401345: 48 8b 44 24 38 mov 0x38(%rsp),%rax
40134a: 4c 89 ee mov %r13,%rsi
40134d: 48 8d 78 e8 lea -0x18(%rax),%rdi
401351: e8 ba fa ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
401356: eb 81 jmp 4012d9 <main+0x349>
401358: 48 89 c3 mov %rax,%rbx
40135b: 48 8b 84 24 b8 00 00 mov 0xb8(%rsp),%rax
401362: 00
401363: 4c 8d 6c 24 0f lea 0xf(%rsp),%r13
401368: 4c 89 ee mov %r13,%rsi
40136b: 48 8d 78 e8 lea -0x18(%rax),%rdi
40136f: e8 9c fa ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
401374: 48 8b 84 24 d8 00 00 mov 0xd8(%rsp),%rax
40137b: 00
40137c: 4c 89 ee mov %r13,%rsi
40137f: 48 8d 78 e8 lea -0x18(%rax),%rdi
401383: e8 88 fa ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
401388: 48 8b b4 24 00 01 00 mov 0x100(%rsp),%rsi
40138f: 00
401390: 48 8d bc 24 f0 00 00 lea 0xf0(%rsp),%rdi
401397: 00
401398: e8 93 01 00 00 callq 401530 <std::_Rb_tree<std::string, std::string, std::_Identity<std::string>, std::less<std::string>, std::allocator<std::string> >::_M_erase(std::_Rb_tree_node<std::string>*)>
40139d: 48 8b 44 24 78 mov 0x78(%rsp),%rax
4013a2: 4c 89 ee mov %r13,%rsi
4013a5: 48 8d 78 e8 lea -0x18(%rax),%rdi
4013a9: e8 62 fa ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
4013ae: 48 8b 84 24 98 00 00 mov 0x98(%rsp),%rax
4013b5: 00
4013b6: 4c 89 ee mov %r13,%rsi
4013b9: 48 8d 78 e8 lea -0x18(%rax),%rdi
4013bd: e8 4e fa ff ff callq 400e10 <std::string::_Rep::_M_dispose(std::allocator<char> const&)@plt>
4013c2: e9 6d ff ff ff jmpq 401334 <main+0x3a4>
4013c7: 48 89 c3 mov %rax,%rbx
4013ca: 4c 8d 6c 24 0f lea 0xf(%rsp),%r13
4013cf: eb a3 jmp 401374 <main+0x3e4>
4013d1: 48 89 c3 mov %rax,%rbx
4013d4: 4c 8d 6c 24 0f lea 0xf(%rsp),%r13
4013d9: eb ad jmp 401388 <main+0x3f8>
4013db: 48 89 c3 mov %rax,%rbx
4013de: 4c 8d 6c 24 0f lea 0xf(%rsp),%r13
4013e3: eb c9 jmp 4013ae <main+0x41e>
4013e5: 48 89 c3 mov %rax,%rbx
4013e8: 4c 8d 6c 24 0f lea 0xf(%rsp),%r13
4013ed: e9 42 ff ff ff jmpq 401334 <main+0x3a4>
4013f2: 48 89 c3 mov %rax,%rbx
4013f5: e9 ec fe ff ff jmpq 4012e6 <main+0x356>
4013fa: 48 89 c3 mov %rax,%rbx
4013fd: e9 ec fe ff ff jmpq 4012ee <main+0x35e>
401402: 66 66 66 66 66 2e 0f data32 data32 data32 data32 nopw %cs:0x0(%rax,%rax,1)
401409: 1f 84 00 00 00 00 00
Common sense dictates that: if it's expected to clearly report any errors >then the appropriate logic would be added. But if a missing file or an empty >error should have functionally identical repercussions as an empty file then >there's little to be gained by an extra check.
Yes, if you run it and the first file doesn't exist, it just creates
an empty output file with no error message.
--- MBSE BBS v1.0.8.4 (Linux-x86_64)
* Origin: UsenetServer - www.usenetserver.com (3:633/280.2@fidonet)