Wednesday, September 11, 2019

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

JiiPee <no@notvalid.com>: Sep 11 11:41AM +0100

I know this is not Windows programming forum, but because I think this
is more like a C++ expertise question (and not Windows) I ask here.
 
So lets say I have a window where I show text after some mouse click. A
naive program, but just to keep it simple.
The question is that should I have only windows-related code in the
Window class and create another class dealing
with the logic of the program?
 
Should all message handler functions forward the call to the program
logic class? So all message handler functions in Window class
should contain normally only 1 line (see example below)?
 
So which one is better 1) or 2) (ignoring the effiency/style issues...)?
I try to make an example illustrating the two approaches
(GetDocument() returns a document object which contains the text
variable drawMessage_):
 
 
1) Mouse logic left in MyWindow class:
 
class MyWindow
{
public:
    void Draw() {
    // draws GetDocument()->drawMessage_ text on to the window
    }
    void MouseClick(Point mousePosition);
};
 
void MyWindow::MouseClick(Point mousePosition)
{
    if(mousePosition.x > 150)
    {
        GetDocument()->drawMessage_ = "Mouse crossed the border";
        Draw();
    }
}
 
========================================================================
 
2) Mouse logic done in MyWindowLogic class:
 
class MyWindowLogic
{
public:
    void Draw() {
    // draws GetDocument()->drawMessage_ text on to the window
    }
    void HandleMouseClick(Point mousePosition);
};
 
void MyWindowLogic::HandleMouseClick(Point mousePosition)
{
    if(mousePosition.x > 150)
    {
        drawMessage_ = "Mouse crossed the border";
        Draw();
    }
}
 
///////////////////////////
 
class MyWindow
{
public:
    void Draw() {
        logic.Draw(); // forward all action to the logic class
    }
    void MouseClick(Point mousePosition);
 
private:
    MyWindowLogic logic;
};
 
void MyWindow::MouseClick(Point mousePosition)
{
    logic.HandleMouseClick(mousePosition); // do all action in logic class
}
 
###########
 
If it an overkill to create a new class for this rather than place all
code in the MyWindow class?
Should we keep things "simple" here and place all such code in the
MyWindow class?
 
Or this kind of separation of logic/windows code is good?
"Öö Tiib" <ootiib@hot.ee>: Sep 11 06:45AM -0700

On Wednesday, 11 September 2019 13:41:55 UTC+3, JiiPee wrote:
> So lets say I have a window where I show text after some mouse click. A
> naive program, but just to keep it simple.
 
All actual software follows input-process-output (IPO) model.
 
> The question is that should I have only windows-related code in the
> Window class and create another class dealing
> with the logic of the program?
 
GUI code is often made to deal with human operator's input and output
and only with it. Then they do not put into GUI classes any code that
a) inputs from any other sources
b) processes the data that was acquired from any sources
c) or outputs its results to any other targets
and basically ... that is it.
Since your example task lacked responsibilities to do anything
of those a), b) or c) it is bad example how to split responsibilities
that way. Note that those a), b) and c) are usually called "program
logic" by such split.
JiiPee <no@notvalid.com>: Sep 11 03:28PM +0100

On 11/09/2019 14:45, Öö Tiib wrote:
> a) inputs from any other sources
> b) processes the data that was acquired from any sources
> c) or outputs its results to any other targets
 
 
Thanks
 
 
Can you give 1-2 examples pls? Does for example b) mean that processing
for example database issues:
 
void MyWindow::MouseClick(Point mousePosition)
{
    if(mousePosition.x > 150)
    {
        // -open database
 
        // -add line into database
 
        Draw();
    }
}
 
 
should not be done like that in MyWindow class? because database is an
outside source?
 
 
> Since your example task lacked responsibilities to do anything
> of those a), b) or c) it is bad example how to split responsibilities
> that way.
 
 
but it answer the question that mouse related code can be done in
MyWindow, I understand. This is a real world example, because
 
I process mouse input in my message handlers.
 
 
> Note that those a), b) and c) are usually called "program
> logic" by such split.
 
ok, so in my example program you would prefer:
 
void MyWindow::MouseClick(Point mousePosition)
{
    if(mousePosition.x > 150)
    {
        GetDocument()->drawMessage_ = "Mouse crossed the border";
        Draw();
    }
}
 
 
so checking/processing the mouse values in MyWindow class function.
JiiPee <no@notvalid.com>: Sep 11 03:45PM +0100

On 11/09/2019 14:45, Öö Tiib wrote:
> b) processes the data that was acquired from any sources
> c) or outputs its results to any other targets
> and basically ... that is it.
 
 
Is there any web site teaching this I could read about it?
JiiPee <no@notvalid.com>: Sep 11 03:53PM +0100

On 11/09/2019 14:45, Öö Tiib wrote:
> of those a), b) or c) it is bad example how to split responsibilities
> that way. Note that those a), b) and c) are usually called "program
> logic" by such split.
 
 
In my real application I have OpenGL code in the View (Windows) class.
So I am thinking that should all this data/functionality relating to
opengl part of the program logic be left in the View or I should move
all those member variables to ProgramLogic class?
 
Like drawing the coordinate axis...should I place that variable m_axis
(doing the coordinate axis) inside my View class and also put its logic
in View class (moving/updating and rotating it)? Or move m_axis to
ProgramLogic class and do its functionality there?
 
 
JiiPee <no@notvalid.com>: Sep 11 03:58PM +0100

On 11/09/2019 15:53, JiiPee wrote:
> So I am thinking that should all this data/functionality relating to
> opengl part of the program logic be left in the View or I should move
> all those member variables to ProgramLogic class?
 
 
I know there is no clear answer, but just asking if this "might" be a
good solution or possibility.
woodbrian77@gmail.com: Sep 10 08:00PM -0700

Shalom
 
This is my messaging/serialization project:
 
https://github.com/Ebenezer-group/onwards
 
 
One area I've not made much progress with is
continuous integration. I've looked at Circleci
and Codeship and some others, but so far haven't
found one that's free and easy to use.
 
Thanks in advance for your constructive comments.
 
 
 
Brian
Ebenezer Enterprises - Enjoying programming again.
http://webEbenezer.net
"Öö Tiib" <ootiib@hot.ee>: Sep 10 11:38PM -0700

> and Codeship and some others, but so far haven't
> found one that's free and easy to use.
 
> Thanks in advance for your constructive comments.
 
TeamCity has likely best GitHub integration.
Other popular choices are Bamboo, Hudson and Jenkins.
Mr Flibble <flibble@i42.removethisbit.co.uk>: Sep 11 03:49PM +0100

> and Codeship and some others, but so far haven't
> found one that's free and easy to use.
 
> Thanks in advance for your constructive comments.
 
You could try CuntCI .. I hear it comes highly recommended by mysogonist
homophobes.
 
/Flibble
 
--
"You won't burn in hell. But be nice anyway." – Ricky Gervais
"I see Atheists are fighting and killing each other again, over who
doesn't believe in any God the most. Oh, no..wait.. that never happens."
– Ricky Gervais
"Suppose it's all true, and you walk up to the pearly gates, and are
confronted by God," Bryne asked on his show The Meaning of Life. "What
will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery
that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates
a world that is so full of injustice and pain. That's what I would say."
Jorgen Grahn <grahn+nntp@snipabacken.se>: Sep 11 08:28AM

On Tue, 2019-09-10, Soviet_Mario wrote:
> sorry ... I find this just now
 
> https://linux.die.net/man/3/strerror
 
> maybe will work ...
 
It will do what the documentation says, and lots of people use it.
Note its limitations, though. It's not thread-safe, for example.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Juha Nieminen <nospam@thanks.invalid>: Sep 11 08:58AM


>> maybe will work ...
 
> It will do what the documentation says, and lots of people use it.
> Note its limitations, though. It's not thread-safe, for example.
 
What do you mean it's not thread-safe? AFAIK errno is thread-local
according to the standard.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 11 11:09AM +0200

>> Note its limitations, though. It's not thread-safe, for example.
 
> What do you mean it's not thread-safe?
> AFAIK errno is thread-local according to the standard.
 
http://man7.org/linux/man-pages/man3/errno.3.html
"errno is thread-local; setting it in one thread does not affect
its value in any other thread."
Bonita Montero <Bonita.Montero@gmail.com>: Sep 11 11:37AM +0200


> http://man7.org/linux/man-pages/man3/errno.3.html
> "errno is thread-local; setting it in one thread does not affect
> its value in any other thread."
 
From the 2007 POSIX draft:
"3.396 Thread
A single flow of control within a process. Each thread has its
own thread ID, scheduling priority and policy, errno value ..."
Keith Thompson <kst-u@mib.org>: Sep 11 02:37AM -0700

>> Note its limitations, though. It's not thread-safe, for example.
 
> What do you mean it's not thread-safe? AFAIK errno is thread-local
> according to the standard.
 
errno is thread-local. That doesn't necessarily mean that strerror()
is thread-safe. For example, a conforming implementation could
always return a pointer to the same static buffer, initialized
with the appropriate message before it returns. And at least one
implementation (x86_64-w64-mingw32-gcc) appears to do exactly that.
 
N1570 7.24.6.2p3:
 
The strerror function is not required to avoid data races with
other calls to the strerror function. The implementation shall
behave as if no library function calls the strerror function.
 
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
Bonita Montero <Bonita.Montero@gmail.com>: Sep 11 11:47AM +0200

There's strerror_r, which is thread-safe.
"Öö Tiib" <ootiib@hot.ee>: Sep 11 04:43AM -0700

On Wednesday, 11 September 2019 12:48:03 UTC+3, Bonita Montero wrote:
> There's strerror_r, which is thread-safe.
 
Somewhere there is strerror_r but not in C++ standard. In C++ standard
there was added strerror_s by C++11 but it may be is deprecated again.
James Kuyper <jameskuyper@alumni.caltech.edu>: Sep 11 08:27AM -0400

On 9/11/19 7:43 AM, Öö Tiib wrote:
> On Wednesday, 11 September 2019 12:48:03 UTC+3, Bonita Montero wrote:
>> There's strerror_r, which is thread-safe.
 
> Somewhere there is strerror_r but not in C++ standard. ...
 
Such a function is specified by POSIX, which doesn't help those
targeting non-POSIX systems.
 
> ... In C++ standard
> there was added strerror_s by C++11 but it may be is deprecated again.
 
It is still mentioned in N4659.pdf, dated 2017-03-01. It is described in
20.1.5.2p10 as a carry-over from C. There is no other description,
you're supposed to cross-reference the C standard for that.
 
The description of sterror_s() in the C standard (C11 K3.7.4.2) does
not, itself, say anything about threads. It simply lacks any clause
comparable to the one in the description of sterror() description which
says "The strerror function is not required to avoid data races with
other calls to the strerror function." (C11 7.24.6.2p3). That's
sufficient, since "Unless explicitly stated otherwise in the detailed
descriptions that follow, library functions shall prevent data races."
(C11 7.1.4p5).
 
Just in case you didn't notice that omission, footnote 312 on the
description of strerror() says "The strerror_s function can be used
instead to avoid data races.".
Manfred <noname@add.invalid>: Sep 11 02:56PM +0200

On 9/11/2019 2:27 PM, James Kuyper wrote:
 
> Just in case you didn't notice that omission, footnote 312 on the
> description of strerror() says "The strerror_s function can be used
> instead to avoid data races.".
 
strerror_s is indeed part of annex K, which has become more and more
controversial, and some implementations (notably glibc) do not support it.
However, a good indication that it is thread safe comes from its
interface: instead of returning a pointer to an internal string buffer,
it requires a writable buffer to be provided by the caller.
Daniel <danielaparker@gmail.com>: Sep 11 07:00AM -0700

On Wednesday, September 11, 2019 at 8:56:57 AM UTC-4, Manfred wrote:
> However, a good indication that it is thread safe comes from its
> interface: instead of returning a pointer to an internal string buffer,
> it requires a writable buffer to be provided by the caller.
 
There appears to be a lot to say about some very simple functions! e.g.
 
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm
 
I hadn't known about this: "since virtually every function in the Bounds
checking library relies on a single process-global runtime-constraint handler,
the APIs are ill-suited for multi-threaded components."
 
Daniel
Juha Nieminen <nospam@thanks.invalid>: Sep 11 09:04AM

> I have no issues with vs or clang.
 
I tried this with clang, and it gives an error. (If the constructor is
commented out, it compiles and works ok.) Am I missing something obvious?
 
//-----------------------------------------------------
#include <iostream>
#include <string>
 
struct MyAlloc
{
using value_type = char;
MyAlloc(int) {}
char* allocate(std::size_t n) { return new char[n]; };
char* allocate(std::size_t n, const void*) { return new char[n]; };
void deallocate(char* ptr, std::size_t) { delete[] ptr; }
bool operator==(const MyAlloc&) const { return true; }
bool operator!=(const MyAlloc&) const { return false; }
};
 
int main(int argc, char** argv)
{
std::basic_string<char, std::char_traits<char>, MyAlloc> str("hello");
std::cout << str << "\n";
}
//-----------------------------------------------------
Daniel <danielaparker@gmail.com>: Sep 11 04:32AM -0700

On Wednesday, September 11, 2019 at 5:04:43 AM UTC-4, Juha Nieminen wrote:
> std::cout << str << "\n";
> }
> //-----------------------------------------------------
 
For a stateful allocator, you need to pass an instance of the constructor
to the object. But MyAlloc also isn't right, it needs to be a template class,
and have a constructor that supports rebinding. As a minimal example, try
 
#include <iostream>
#include <string>
#include <memory>
 
template <class T>
struct MyAlloc
{
using value_type = T;
using size_type = std::size_t;
using propagate_on_container_move_assignment = std::true_type;
 
MyAlloc(int) {}
 
template< class U >
MyAlloc(const MyAlloc<U>&) noexcept {}
 
T* allocate(size_type n)
{
return static_cast<T*>(::operator new(n * sizeof(T)));
}
 
void deallocate(T* ptr, size_type) noexcept
{
::operator delete(ptr);
}
 
bool operator==(const MyAlloc&) const { return true; }
bool operator!=(const MyAlloc&) const { return false; }
};
 
int main()
{
std::basic_string<char, std::char_traits<char>, MyAlloc<char>> str("hello", MyAlloc<char>(1));
std::cout << str << "\n";
}
Daniel <danielaparker@gmail.com>: Sep 11 04:39AM -0700

On Tuesday, September 10, 2019 at 3:25:40 AM UTC-4, Öö Tiib wrote:
 
> Is it regression so someone had added the _Alloc() back,
> or are you using very old gcc?
 
I believe I'm using the correct versions of gcc in the travis builds, but I
think what's happening is that I'm picking up a version of the library that is
#if'ed compiled for gcc's old reference counting strings, viz
 
#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
if (__beg == __end && __a == _Alloc())
return _S_empty_rep()._M_refdata();

No comments: