- In C, when stdin fails it works again in the future, the C ++ cin not? - 6 Updates
- std::bind overloaded class method - 3 Updates
- (learning) out_of_range exception is not working(?) - 3 Updates
- Adding a function to std::exception and company - 2 Updates
- "SleepPat.HTM" is dense, rich and complex, like my source code. - 1 Update
- (learning) out_of_range exception is not working(?) - 5 Updates
- "Bjarne Stroustrup mines generic programming for a better C++" - 4 Updates
Christiano <christiano@engineer.com>: Jan 25 11:29AM -0800 I come from the C language, see the following example: // {======= get.c ============ #include <stdio.h> int main(void) { char c; char d; c = getchar(); d = getchar(); putchar(c); printf("\n"); putchar(d); printf("\n"); return 0; } // }======= end get.c ======== Running (comments using notation ## comments ##): debian@debian:~/principles$ gcc get.c -o get debian@debian:~/principles$ ./get ##First I press Ctrl+D## ##Ctrl+D again## � � debian@debian:~/principles$ That is, the two getchar tried to read the stdin and I pressed Ctrl + D to not feed the empty stdin. Ok, Let's see something equivalent in C ++. // {=========== get++.cpp =========== #include <iostream> using namespace std; int main(void) { char c; char v; cin >> c; cin >> v; cout << c; cout << endl; cout << v; cout << endl; return 0; } // }=========== end get++.cpp ====== There is a difference in behavior here. Running (comments using notation ## comments ##): debian@debian:~/principles$ g++ get++.cpp -o get++ debian@debian:~/principles$ ./get++ ##I press Ctrl+D just one time## � @ debian@debian:~/principles$ That is, the first crash of cin was enough to fail the second without giving me the chance to fill the stdin in the second time. I just pressed Ctrl + D once and that was enough for cin >> v to fail. Now, I will show a code based from book "Programming: Principles and Practice Using C++ Second Edition": // {========= tdx.cpp =========== #include "std_lib_facilities.h" double some_function() { double d = 0; cin >> d; if(!cin) error("Couldn't read a double in some_function()"); return d; } int main(void) try { double x = some_function(); cout << "The value read is: " << x << endl; return 0; } catch(runtime_error &e) { cerr << "runtime error: " << e.what() << "\n"; keep_window_open(); return 1; } // } ======= end tdx.cpp ======== Where std_lib_facilities.h is: http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h Running (comments using notation ## comments ##): debian@debian:~/principles$ g++ tdx.cpp -o tdx debian@debian:~/principles$ ./tdx | ##the cin >> d wants a double, i will give "|" to force the fail## runtime error: Couldn't read a double in some_function() Please enter a character to exit ##Here he passed straight through without pausing.## debian@debian:~/principles$ The program is designed to "pause" when the "double type" reading fails, before exiting. But this is not what happens, as you can see. Looking inside std_lib_facilities.h, you can see what keep_window_open () is: inline void keep_window_open() { cin.clear(); cout << "Please enter a character to exit\n"; char ch; cin >> ch; return; } That is, "the first crash of cin was enough to fail the second without giving me the chance to fill the stdin in the second time." Again. My question is: Is this a book error? Is this behavior normal? I've scanned the pages, here: http://imgur.com/a/8GEkE http://imgur.com/a/dNWGe |
Bo Persson <bop@gmb.dk>: Jan 25 08:44PM +0100 On 2017-01-25 20:29, Christiano wrote: > debian@debian:~/principles$ > That is, the first crash of cin was enough to fail the second without giving me the chance to fill the stdin in the second time. > I just pressed Ctrl + D once and that was enough for cin >> v to fail. This is by design. cin will remember the failure to read and will not attempt to read anything more, until you call cin.clear() to clear the error state. Bo Persson |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 25 09:05PM +0100 On 25.01.2017 20:29, Christiano wrote: > � > � > debian@debian:~/principles$ Yep, the C FILE* streams do not have EOF as a state, they just report EOF when they read in zero bytes – which is what happens when you press Ctrl+D without having typed anything on the line, there is nothing, so the read returns an empty sequence of bytes. At one time long ago this was used in a "readslow" program to follow the thinking of a famous chess program. Wait let me google that. OK found something about it, not the chess tournament thing, but it was mentioned in the old classic "The UNIX Programming Environment" by Kernighan & Pike: [TUPE] > costly in CPU time. Thus this version of readslow copies its input up to the > end of file, sleeps a while, then tries again. If more data arrives while it is > asleep, it will be read by the next read. [/TUPE] Continuing with your posting: On 25.01.2017 20:29, Christiano wrote: > } > // }=========== end get++.cpp ====== > There is a difference in behavior here. Yes, them dang iostreams are /stateful/. Once a stream gets into an error state, which is a kind of "ignore all attempted operations" mode, you have to clear it in order to continue. In passing, `f(void)` is a C-ism. In C the `void` there ensures that the function is declared as taking no arguments, as opposed to an arbitrary number of arguments with just `f()`. But in C++ `f()` says directly that it takes no arguments, there's no need for `f(void)`. > } > That is, "the first crash of cin was enough to fail the second without giving me the chance to fill the stdin in the second time." Again. > My question is: Is this a book error? Yes. But it's a different issue. The `keep_window_open` function does clear the stream error state, via a call to `clear`. But it fails to empty the input buffer, where characters from the failed read still linger. It could empty the input buffer with a call to `ignore`. Check whether this bug is already in the book's errata list. If it isn't then report it to Bjarne. > Is this behavior normal? Yes, it's by design. But note that the `keep_window_open` issue is not the same as the end of file state you encountered earlier. For the first issue, about EOF, try out the following program: #include <iostream> #include <string> using namespace std; auto main() -> int { double x; cout << "? "; cin >> x; if( cin.fail() ) { cout << "Failed. This was left in input buffer: `"; cin.clear(); string s; getline( cin, s ); cout << s << "`." << endl; } else { cout << "Oh, the number " << x << "! Thanks! :)" << endl; } } > I've scanned the pages, here: > http://imgur.com/a/8GEkE > http://imgur.com/a/dNWGe Cheers & hth., - Alf |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 25 09:08PM +0100 On 25.01.2017 21:05, Alf P. Steinbach wrote: > For the first issue, about EOF, try out the following program: I meant, for the second issue, about a failed read op. Grr. Sorry 'bout that, - Alf |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 25 10:30PM On Wed, 2017-01-25, Christiano wrote: ... > ??? > ??? > debian@debian:~/principles$ You're describing feeding a process EOF on stdin more than once. Can you see any practical use for this? I have noticed the behavior, but I decided it has no practical use, and that a program is better off honoring the EOF. Especially since the behavior is limited to interactive use. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 26 12:02AM +0100 On 25.01.2017 23:30, Jorgen Grahn wrote: > You're describing feeding a process EOF on stdin more than once. > Can you see any practical use for this? > I have noticed the behavior, but I decided it has no practical use, That may well be the case today. It wasn't always so. It was used. > and that a program is better off honoring the EOF. Especially since > the behavior is limited to interactive use. Well, that's incorrect. You can read more about it in my reply to the OP, earlier. Cheers & hth., - Alf |
"Christopher J. Pisz" <cpisz@austin.rr.com>: Jan 25 07:45AM -0600 I am trying to try out std::async and futures In order to do this, I need to bind a class method I would like run async. The class method in question has overloads. One version is the top level, another is the recursive portion. etc. What is the bind syntax? It usually has worked fine for me with std::bind(&MyClass::MyMethod, this, std::placeholders::_1); but now I am dealing with an overloaded method with multiple arguments. I am trying and failing with: //------------------------------------------------------------------------------ MyThing::Permutations MyThing::GetPermutations() const { std::vector<std::future<Permutations> > futures; auto func = std::bind<MyThing::Permutations(size_t, size_t)>(&MyThing::GetPermutations, this, std::placeholders::_1, std::placeholders::_2); /* for( size_t x = 0; x < m_numColumns; ++x ) { for( size_t y = 0; y < m_numRows; ++y ) { std::async(std::launch::async, &Board::GetPermutations, this, x, y); } } */ GetPermutations(0, 0); } with a class that looks like: //------------------------------------------------------------------------------ class MyThing { public: typedef std::vector<std::string> Permutations; MyThing(); ~MyThing(); Permutations GetPermutations() const; protected: typedef std::vector<std::vector<bool> > UsedMap; Permutations GetPermutations(size_t startingCoordinates_X , size_t startingCoordinates_Y) const; Permutations GetPermutations(size_t startingCoordinates_X , size_t startingCoordinates_Y , UsedMap usedMap) const; }; |
"Christopher J. Pisz" <cpisz@austin.rr.com>: Jan 25 08:12AM -0600 On 1/25/2017 7:45 AM, Christopher J. Pisz wrote: > , size_t startingCoordinates_Y > , UsedMap usedMap) const; > }; I got it. Twas the const keyword that was missing it seems. auto func = std::bind(static_cast<MyThing::Permutations(MyThing::*)(size_t, size_t) const>(&MyThing::GetPermutations), this, std::placeholders::_2); |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Jan 25 08:19PM On Wed, 25 Jan 2017 08:12:35 -0600 > std::bind(static_cast<MyThing::Permutations(MyThing::*)(size_t, > size_t) > const>(&MyThing::GetPermutations), this, std::placeholders::_2); You disambiguate overloads with static_cast. That was the bit that made it work for you (unless your original version contained a typing error so the static_cast was in your real code but omitted from your posting by mistake). This did of course also require you to get the signature right, which you did in your second version. Chris |
ram@zedat.fu-berlin.de (Stefan Ram): Jan 24 11:56PM >So this must be an error in PPP2 (principles and practices >programming using c ++ second edition). >See the page 149: I don't watch pictures from web sites, but I don't believe that you represented the title of the book correctly, and I don't believe that a book co-authored by Bjarne Stroustrup contains such a blatand mistake. |
ram@zedat.fu-berlin.de (Stefan Ram): Jan 25 12:12AM >remember any consensus being reached. But it's worth noting that with >most compilers, with proper tool usage you can do this also with simple >`[i]` indexing, possibly with crash response instead of exception. The following is one of the programs written by Bjarne Stroustrup that I like the most. Bjarne Stroustrup himself writes about this program: »I often use a simple range-checking adaptation of vector:«. That is, it is something he himself uses often. template<typename T> class Vec : public std::vector<T> { public: using vector<T>::vector; T& operator[](int i) { return vector<T>::at(i); } const T& operator[](int i) const { return vector<T>::at(i); } }; (And I only now have become aware of that the way that he uses the braces in the method declarations of this program seems to be the way I use them: »{« at the start of a line, followed by a space, »}« at the end of a line, preceded by a space.) |
ram@zedat.fu-berlin.de (Stefan Ram): Jan 25 07:50PM >That is, the first crash of cin was enough to fail the second >without giving me the chance to fill the stdin in the second >time. I don't know whether this is your problem, but you can clear some failbits (or such) using ::std::cin.clear(); , and sometimes it also helps to clear the current line from the input buffer ::std::cin.ignore ( ::std::numeric_limits< ::std::streamsize >::max(), '\n' ); . Some relevant includes for this might be #include <iostream> #include <ostream> #include <istream> #include <limits> . |
woodbrian77@gmail.com: Jan 25 09:58AM -0800 I'd like to see something like this added to std::exception and types derived from it: virtual ::std::string_view what_view () const noexcept; In this file: https://github.com/Ebenezer-group/onwards/blob/master/cmwAmbassador.cc there's some code like this: }catch(::std::exception const& ex){ syslog_wrapper(LOG_ERR,"Mediate request: %s",ex.what()); middle_messages_front::Marshal(localsendbuf,false,ex.what()); } I can't change the first call to "what" unless I find an alternative to syslog. But I could change the second call to "what" to "what_view" and avoid the need to recalculate the length of the string. The proposed function could be implemented like this: virtual ::std::string_view what_view () const noexcept { return std::string_view(whatStr); } // where whatStr is a std::string. At least that's how I would do it here: https://github.com/Ebenezer-group/onwards/blob/master/ErrorWords.hh I'm not planning on going to the upcoming C++ standardization meeting in Kona, Hawii, but if someone is, feel free to mention this. Thanks. Brian Ebenezer Enterprises - In G-d we trust. http://webEbenezer.net |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 25 08:17PM +0100 > I can't change the first call to "what" unless I find an alternative to > syslog. But I could change the second call to "what" to "what_view" > and avoid the need to recalculate the length of the string. If you create your own exception class you can provide a method that returns a string view, to avoid copying of the string. Think also about creating an exception instance from a string view. One doesn't want conversion to `std::string` there because that can throw. > I'm not planning on going to the upcoming C++ standardization > meeting in Kona, Hawii, but if someone is, feel free to mention > this. Thanks. Just a side note: exceptions and strings have a circular dependency relationship, which makes it difficult to implement it all in header only modules. Cheers!, - Alf |
Jeff-Relf.Me <@.>: Jan 25 12:44AM -0800 |
Christiano <christiano@engineer.com>: Jan 24 03:39PM -0800 On Tuesday, January 24, 2017 at 8:25:42 PM UTC-2, Öö Tiib wrote: > Undefined behavior may be whatever. It may output "v[5]==0" > or it may crash or it may conjure demons out of your nose. > Generally we avoid writing code that contains undefined behaviors. Hi, thank you. I have rewritten the code (at the end of this post) adding ".at" instead .[x]. Now it is working as expected: debian@debian:~/principles$ ./a.out 1 2 3 4 5 v[0]==1 v[1]==2 v[2]==3 v[3]==4 v[4]==5 Ops, range error debian@debian:~/principles$ So this must be an error in PPP2 (principles and practices programming using c ++ second edition). See the page 149: http://imgur.com/a/E9m6Q /// my new code2 #include <iostream> #include <vector> #include <stdexcept> using namespace std; int main(void) try { vector<int> v; for(int x;cin>>x;) v.push_back(x); for(int i=0;i<=v.size();++i) cout << "v[" << i << "]=="<<v.at(i)<<'\n'; } catch(out_of_range) { cerr << "Ops, range error\n"; return 1; } catch(...) { cerr <<"Exception: something get wrong\n"; return 2; } |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 25 12:55AM +0100 On 25.01.2017 00:39, Christiano wrote: > So this must be an error in PPP2 (principles and practices > programming using c ++ second edition). See the page 149: > http://imgur.com/a/E9m6Q It's just a unclear language, in the sense of using /too few words/ to explain something, so that the point flies by the casual reader like a passenger jet high above: such a jet liner is usually not even noticed. "[The subscript operation] can check (and the `vector` we are using does" You need to read that five times, say, in order to get the word count up to an appropriate level commensurate with its importance. ;-) That said, the wording is misleading in that it indicates that a given vector implementation will either have a bounds-checking `operator[]` or not. More commonly this can be specified when you build your program, and instead of throwing an exception, it might just terminate the program. The options for turning on and off such checking vary greatly between compilers; it's not specified by the Holy Standard. At one time great debates raged here in clc++ about whether using `.at` was a good idea in order to catch subscript range errors. I can't remember any consensus being reached. But it's worth noting that with most compilers, with proper tool usage you can do this also with simple `[i]` indexing, possibly with crash response instead of exception. Cheers & hth., - Alf |
Christiano <christiano@engineer.com>: Jan 24 04:37PM -0800 Hi, Alf, Thank you, you made me remember that the author occultly uses a header: http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h So I decided to investigate if he was doing a special vector version, as you said. See this code section: template< class T> struct Vector : public std::vector<T> { using size_type = typename std::vector<T>::size_type; #ifdef _MSC_VER // microsoft doesn't yet support C++11 inheriting constructors Vector() { } explicit Vector(size_type n) :std::vector<T>(n) {} Vector(size_type n, const T& v) :std::vector<T>(n,v) {} template <class I> Vector(I first, I last) : std::vector<T>(first, last) {} Vector(initializer_list<T> list) : std::vector<T>(list) {} #else using std::vector<T>::vector; // inheriting constructor
Subscribe to:
Post Comments (Atom)
|
No comments:
Post a Comment