- A decent read/write mutex... - 1 Update
- linker error - 6 Updates
- Why this UTF-8-conversion code works with Visual C++ and not with g++? - 2 Updates
- peformance of wait notify concept of condition variable - 1 Update
- How to use the second constructor? - 1 Update
"Chris M. Thomasson" <invalid@invalid.invalid>: May 13 04:11PM -0700 On 4/15/2017 10:47 PM, Chris M. Thomasson wrote: > If you read all of the data in the links, one can implement it for > themselves. Is there any interest in my upcoming pure c++ std impl of > this rw-mutex? Thanks. Nobody seems interested. Damn it! |
alexo <alessandro.volturno@libero.it>: May 13 02:05AM +0200 Hello all, can you find the bug in this code snipped? It is a class template I'm trying to write. but the linker complains and reminds me I'm a beginner :( thank you #include <iostream> #include <typeinfo> #include <cstring> using std::string; using std::ostream; /// the class' declaration template <class T> class MyClass { T *data; public: MyClass(T); MyClass(const MyClass<T> &); ~MyClass(); friend ostream & operator<<(ostream &, const MyClass<T> &); }; /// the class' definition // constructor template <class T> MyClass<T>::MyClass(T val) { data = new T; data = val; } // copy constructor template <class T> MyClass<T>::MyClass(const MyClass<T> &obj) { data = new T; if( typeid(T) == typeid(char *) ) { int len = strlen(obj.data); strncpy(data, obj.data, len+1); } else { data = obj.data; } } // destructor template <class T> MyClass<T>::~MyClass() { delete data; } // stream insertion operator template <class T> ostream &operator<<(ostream &s, const MyClass<T> &obj) { return s << obj.data; } /// the main function int main() { MyClass<char *> test("Hello guys!"); cout << test << endl; return 0; } |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 13 02:48AM +0200 On 13-May-17 2:05 AM, alexo wrote: > can you find the bug in this code snipped? > It is a class template I'm trying to write. > but the linker complains and reminds me I'm a beginner :( See FAQ item §5.8 "How do I post a question about code that doesn't work correctly?", e.g. at <url: http://www.dietmar-kuehl.de/mirror/c++-faq/how-to-post.html#faq-5.8>. In particular item 7. It's generally a good idea to check the FAQ before posting. :) > cout << test << endl; > return 0; > } I haven't tried your code, but maybe you need to write template <class T> ostream &operator<< <T>(ostream &s, const MyClass<T> &obj) Have you tried that? Cheers & hth., - Alf |
Ben Bacarisse <ben.usenet@bsb.me.uk>: May 13 02:23AM +0100 > MyClass(const MyClass<T> &); > ~MyClass(); > friend ostream & operator<<(ostream &, const MyClass<T> &); You need friend ostream & operator<< <>(ostream &, const MyClass<T> &); here, and operator<< to be previously declared. That requires the class to be pre-declared (as a template type) above the class definition: template <class T>class MyClass; template <class T> ostream & operator<<(ostream &, const MyClass<T> &); > { > data = new T; > data = val; The types are wrong here. I think you meant *data = val; > ostream &operator<<(ostream &s, const MyClass<T> &obj) > { > return s << obj.data; And this prints a pointer. I think you meant s << *obj.data; > int main() > { > MyClass<char *> test("Hello guys!"); String literals are of type const char * (well, they are arrays but they convert to pointers) so you can't convert "..." to a char *. > cout << test << endl; And here you need std::cout and std::endl; -- Ben. |
alexo <alessandro.volturno@libero.it>: May 13 07:03PM +0200 Il 13/05/2017 02:48, Alf P. Steinbach ha scritto: > http://www.dietmar-kuehl.de/mirror/c++-faq/how-to-post.html#faq-5.8>. > In particular item 7. > It's generally a good idea to check the FAQ before posting. :) Here is the output [a bit manipulated to make it more readable] of the compilation. warning: friend declaration 'std::ostream& operator<<(std::ostream&, const MyClass<T>&)' declares a non-template function [-Wnon-template-friend] (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) in function 'int main()': warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings] In function `main': undefined reference to `MyClass<char*>::MyClass(char*)'| Undefined reference to `operator<<(std::ostream&, MyClass<char*> const&)' undefined reference to `MyClass<char*>::~MyClass()'| undefined reference to `MyClass<char*>::~MyClass()'| error: ld returned 1 exit status| > I haven't tried your code, try it please, because I'm going crazy to find the subtle error that prevents the compilation. Thank you |
alexo <alessandro.volturno@libero.it>: May 13 07:07PM +0200 Il 13/05/2017 03:23, Ben Bacarisse ha scritto: >> data = new T; >> data = val; > The types are wrong here. I think you meant *data = val; you are right... :) >> { >> return s << obj.data; > And this prints a pointer. I think you meant s << *obj.data; and you are right again > And here you need std::cout and std::endl; >> return 0; >> } forgotten :) |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 13 08:46PM +0200 On 13-May-17 7:03 PM, alexo wrote: >> I haven't tried your code, > try it please, because I'm going crazy to find the subtle error that > prevents the compilation. OK. Most of those are spurious, unreal errors. The compiler gets confused due to the real technical errors. With the /language/ errors fixed it compiles: --------------------------------------------------------------------- #include <iostream> #include <typeinfo> #include <cstring> using std::string; using std::ostream; template <class T> class MyClass { T *data; public: MyClass(T); MyClass(const MyClass<T> &); ~MyClass(); template< class U > //! friend ostream & operator<<(ostream &, const MyClass<U> &); //! }; template <class T> MyClass<T>::MyClass(T val) { data = new T; *data = val; //! } template <class T> MyClass<T>::MyClass(const MyClass<T> &obj) { data = new T; if( typeid(T) == typeid(char *) ) { int len = strlen(obj.data); strncpy(data, obj.data, len+1); } else { data = obj.data; } } template <class T> MyClass<T>::~MyClass() { delete data; } template <class T> ostream &operator<<(ostream &s, const MyClass<T> &obj) { return s << obj.data; } int main() { MyClass<char const*> test("Hello guys!"); //! using namespace std; cout << test << endl; } --------------------------------------------------------------------- Note that there are still a host of errors in this code, but the compiler I used, with the options I used, wasn't smart enough to diagnose them, and isn't required by the standard to diagnose them. As general advice, instead of dealing with `char const*` and `new` etc., just use `std::string` and `std::vector`. More comfortable, more safe, more easy, can even be faster. ;-) Cheers!, - Alf |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 13 08:51AM +0200 I'm working on a (raw C++) minimal library I've called "stdlib", a portable wrapper for the ordinary C++ standard library that • sets up working Unicode based console i/o for the standard streams, in particular so they'll work for international text in Windows, • adds necessary defines for <math.h> to get M_PI etc, • provides functionality-area headers, e.g. all of i/o, etc. Because I realized that this is more fundamental than the Expressive C++ stuff. For example, the following should work fine with general Unicode text in Windows: #include <stdlib/iostream.hpp> #include <stdlib/string.hpp> using namespace std; auto main() -> int { cout << "Hi, what's your name? "; string name; getline( cin, name ); cout << "Pleased to meet you, " << name << "!" << endl; } The header wrappers used here install custom iostream buffers that do UTF-8 / UTF-16 conversion via std::codecvt_utf8_utf16<wchar_t>, and access the Windows console Unicode API directly without dragging in the <windows.h> header. And it works nicely with Visual C++, but with g++ I get Chinese or whatever it is (garbage?), showing in the console as just squares: [C:\my\dev\libraries\stdlib\examples\hello_world] > g++ hello_world.cpp && a 䠀椀Ⰰ 眀栀愀琀ᤠ猀 礀漀甀爀 渀愀洀攀㼀 my ÆØÅ-input 倀氀攀愀猀攀搀 琀漀 洀攀攀琀 礀漀甀Ⰰ 洀礀 였�씀ⴀ椀渀瀀甀琀℀ [C:\my\dev\libraries\stdlib\examples\hello_world] > cl hello_world.cpp /Feb /wd4373 && b hello_world.cpp Hi, what's your name? my ÆØÅ-input Pleased to meet you, my ÆØÅ-input! [C:\my\dev\libraries\stdlib\examples\hello_world] > _ With wide text i/o the thing works also with g++, so it's not the no-windows.h-binding to the API that's at fault, hence my strong assumption that it's the UTF-8 / UTF-16 conversion. The library is header only, at <url: https://github.com/alf-p-steinbach/stdlib>. The conversion sources are all in "workarounds" folder. Possibly the bug resides / the bugs reside in "source/workarounds/impl/windows_console_io/Byte_to_wide_converter.hpp", ------------------------------------------------------------------------ #pragma once // Source encoding: utf-8 ∩ // #include <stdlib/workarounds/impl/windows_console_io/Codecvt.hpp> // Copyright © 2017 Alf P. Steinbach, distributed under Boost license 1.0. #include <codecvt> // std::codecvt_utf8 namespace stdlib{ namespace impl{ namespace windows_console_io{ using std::codecvt_utf8_utf16; using Codecvt = codecvt_utf8_utf16<wchar_t>; using Codecvt_result = decltype( Codecvt::ok ); using Codecvt_state = Codecvt::state_type; }}} // namespace stdlib::impl::windows_console_io ------------------------------------------------------------------------ ------------------------------------------------------------------------ #pragma once // Source encoding: utf-8 ∩ // #include <stdlib/workarounds/impl/windows_console_io/Byte_to_wide_converter.hpp> // Copyright © 2017 Alf P. Steinbach, distributed under Boost license 1.0. #include <assert.h> // assert #include <stdlib/workarounds/impl/Size.hpp> // Size #include <stdlib/workarounds/impl/windows_console_io/Codecvt.hpp> // Codecvt, Codecvt_result #include <stdlib/workarounds/impl/windows_console_io/constants.hpp> // ascii::del namespace stdlib{ namespace impl{ namespace windows_console_io{ using std::begin; using std::copy; using std::end; class Byte_to_wide_converter { public: static Size constexpr in_buf_size = general_buffer_size; private: Codecvt codecvt_{}; Codecvt_state conversion_state_{}; // mb_state char in_buf_[in_buf_size]; Size n_buffered_ = 0; auto start_of_buffer() -> char* { return begin( in_buf_ ); } auto put_position() -> char* { return begin( in_buf_ ) + n_buffered_; } auto beyond_buffer() -> char const* { return end( in_buf_ ); } public: auto n_buffered() const -> Size { return n_buffered_; } auto available_space() const -> Size { return in_buf_size - n_buffered_; } void add( Size const n, char const* const chars ) { assert( n <= available_space() ); copy( chars, chars + n, put_position() ); n_buffered_ += n; } auto convert_into( wchar_t* const result, Size const result_size ) -> Size { char const* p_next_in = start_of_buffer(); wchar_t* p_next_out = result; for( ;; ) { auto const p_start_in = p_next_in; auto const p_start_out = p_next_out; auto const result_code = static_cast<Codecvt_result>( codecvt_.in( conversion_state_, p_start_in, put_position(), p_next_in, // begin, end, beyond processed p_start_out, result + result_size, p_next_out // begin, end, beyond processed ) ); switch( result_code ) { case Codecvt::ok: case Codecvt::partial: case Codecvt::noconv: { copy<char const*>( p_next_in, put_position(), start_of_buffer() ); n_buffered_ = put_position() - p_next_in; return p_next_out - result; } case Codecvt::error: { *p_next_out++ = static_cast<wchar_t>( ascii::del ); break; // p_next_in points past the offending byte. } default: { assert(( "Should never get here.", false )); throw 0; break; } } } } }; }}} // namespace stdlib::impl::windows_console_io ------------------------------------------------------------------------ Maybe someone has encountered the same phenomenon? Or maybe someone just by looking at it can see a glaringly obvious bug? I know I often fail to see my own bugs, while I can spot others' bugs easily. Hopefully! Cheers! - Alf |
Christian Gollwitzer <auriocus@gmx.de>: May 13 10:56AM +0200 Am 13.05.17 um 08:51 schrieb Alf P. Steinbach: > etc. > Because I realized that this is more fundamental than the Expressive C++ > stuff. So essentially it fixes a broken platform. > For example, the following should work fine with general Unicode text in > Windows: ...on Linux and OSX terminals it works without such quirks. Which is why many programmers are annoyed of developing under Windows, at least if they target platform independent code. I think this is useful, indeed. About your "Expressive C++" ;) stuff - I think it does not result in a usable language, but that is mostly the failure of the limited power of the preprocessor. It does indeed have a point, IMHO - it shows, that a statically compiled zero-overhead language like C++ /could/ have a feature-rich expressive syntax competing with modern "scripting" languages such as Python. I am quite sure, that C++, if designed from the grounds up with todays compiler technology available, would give a clean, superfast and comfortable programming environment. There is simply too much ballast along the way now. Template metaprogramming, seriously? You misuse the static typesystem as a functional programming language preprocessor embedded in the compiler with a brainfuck-like syntax and almost no overlap with the main language syntax? This sounds sooo wrong, and yet many "modern" features depend on it???? Christian |
"Chris M. Thomasson" <invalid@invalid.invalid>: May 12 10:26PM -0700 On 5/4/2017 12:09 PM, Chris M. Thomasson wrote: >> This code does the same thing I wrote: it handles the I/O-postprocessing >> depending on the return-value of ReadFile!!! > Will read it. Thank you. Fwiw, even if ReadFile returns TRUE, you will get a IO completion. If the HANDLE is hooked up to an IOCP, that means you will get a completion on GQCS. This is perfectly normal. There is nothing wrong or odd here. Wrt IOCP, your code does not need to do anything special when ReadFile returns TRUE. Its a 1 to 1 relationship. Think of: [0]:ReadFile goes ERROR_IO_PENDING [1]:ReadFile goes ERROR_IO_PENDING [2]:ReadFile returns TRUE [3]:ReadFile goes ERROR_IO_PENDING You will get 4 completions from GQCS. That's that. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 13 02:43AM +0200 On 12-May-17 4:07 PM, fl wrote: > [snip] When I run below code, I find one calls assignment > while the other calls copy constructor. You mean, one declaration uses the converting constructor while the other uses the copy constructor. > It is obvious it is caused by the > template parameter <W>. It is still a surprise to me. I thought both should > call copy constructor. Can you explain it to me? `sc_biguint<3>` is a different type than `sc_biguint<4>`. So an instance of the first can't be used directly where a reference to the second is required, or vice versa. This rules out use of the copy constructor in one case: it can't be called with an argument that can't be converted to the type of the formal argument. However, these types share a common base class. > sc_biguint( const sc_unsigned& v ) > : sc_unsigned( W ) > { *this = v; } Cheers & hth., - Alf |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment