Saturday, May 13, 2017

Digest for comp.lang.c++@googlegroups.com - 11 updates in 5 topics

"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: