Monday, February 11, 2019

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

ailynkasabroso@gmail.com: Feb 10 09:07PM -0800

Hello friends.
I struggle to understand why this code doesn't compile - https://wandbox.org/permlink/BcFlcQTidpCg0lsJ
 
I tried gcc and ms vc++. They both have very similar errors.
 
What is strange that if we move friend expression before declaring any class members then code compiles fine. Or we can remove member operator + then it compiles too.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 11 10:27AM +0100

> Hello friends.
> I struggle to understand why this code doesn't compile - https://wandbox.org/permlink/BcFlcQTidpCg0lsJ
 
You should put the code /in the question/.
 
 
------------------------------------------------------------------------------------------------
#include <iostream>
 
template<typename T>
class Test;
 
template<typename T>
Test<T> operator + (const Test<T>& lhs, const Test<T>& rhs);
 
template<typename T>
class Test
{
// this "friend" compiles
//friend Test<T> operator + <T> (const Test<T>& lhs, const Test<T>& rhs);
public:
explicit Test(T value)
: m_value(value)
{
}
 
// we comment this operator then it compiles
Test operator + (T value)
{
return Test(m_value + value);
}
 
private:
// this "friend" doesn't compile
friend Test<T> operator + <T> (const Test<T>& lhs, const Test<T>& rhs);
// this "friend" compiles
//friend Test<T> operator + (const Test<T>& lhs, const Test<T>& rhs)
//{
// return Test<int>(lhs.m_value + rhs.m_value);
//}
T m_value;
};
 
template<typename T>
Test<T> operator + (const Test<T>& lhs, const Test<T>& rhs)
{
return Test<T>(lhs.m_value + rhs.m_value);
}
 
main(int argc, char* argv[])
{
Test<int> t1(5);
Test<int> t2(6);
Test<int> t3 = t1 + t2;
}...................................................................................................
 
 
Note that since `main` lack a return value specification this code is
invalid as standard C++, and Visual C++ does not compile it.
 
g++ /should/ diagnose this by default, but MinGW g++ 8.2.0 doesn't even
warn when I explicitly enable the warning,
 
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wreturn-type
 
 
> I tried gcc and ms vc++. They both have very similar errors.
 
You should specify the build command(s) /in the question/.
 
$ g++ prog.cc -Wall -Wextra
-I/opt/wandbox/boost-1.69.0/gcc-8.2.0/include -std=gnu++2a
 
Instead of a gcc-specific cryptic specification of standard like
"gnu++2a", which could mean anything, use e.g. "c++14".
 
 
 
> What is strange that if we move friend expression before declaring
> any class members then code compiles fine. Or we can remove member
> operator then it compiles too.
 
Well,
 
friend Test<T> operator + <T>
 
is a syntax error.
 
When you fix that by removing the last `<T>`, g++ helpfully reports that it
 
"declares a non-template function"
 
When you fix /that/, by templating the `friend` declaration,
 
template< class U >
friend Test<U> operator + (const Test<U>& lhs, const Test<U>& rhs);
 
 
it compiles.
 
You then have /two/ operator+ definitions. However, the one inline in
the class has right hand side argument of type `T`, so it's not
considered for the call in `main`. So you get a call of the free function.
 
When you fix that it still compiles, because the lookup rules are such
that when a definition (or more generally a declaration) is found in the
class, declarations at namespace level are not considered. I.e. you then
get a call of the member version. And I suggest that you just remove
that, because the free function supports implicit conversion in both
argument positions, so it's the more general variant.
 
 
Cheers & hth.,
 
- Alf
red floyd <dont.bother@its.invalid>: Feb 11 09:51AM -0800

On 2/11/2019 1:27 AM, Alf P. Steinbach wrote:
 
 
> g++ /should/ diagnose this by default, but MinGW g++ 8.2.0 doesn't even
> warn when I explicitly enable the warning,
 
> http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wreturn-type
 
As I recall, main() has an implicit "return 0". Unfortunately, the
only standard I have access to at the moment is C++03. In that
standard, see 3.6.1/5:
 
"... If control reaches the end of main without encountering a return
statement, the effect is that of executing return 0;"
 
So it is defined, it is valid, and no warning is required. At least
as of C++03.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 11 08:14PM +0100

On 11.02.2019 18:51, red floyd wrote:
> statement, the effect is that of executing return 0;"
 
> So it is defined, it is valid, and no warning is required.  At least
> as of C++03.
 
The problem isn't lack of a `return` statement, it's the implicit `int`.
 
Cheers!,
 
- Alf
James Kuyper <jameskuyper@alumni.caltech.edu>: Feb 11 02:33PM -0500

On 2/11/19 12:51, red floyd wrote:
> standard, see 3.6.1/5:
 
> "... If control reaches the end of main without encountering a return
> statement, the effect is that of executing return 0;"
 
Yes, but "the effect of executing return 0;" depends upon how the
function is declared. If it's declared as returning a type that "int"
can be implicitly converted to, the behavior is to convert 0 to that
type and return it. If it's declared as returning any other type, or as
returning void, it's a violation of a diagnosable rule specified by the
standard (9.6.3p2); a diagnostic is required (4.1p2).
And if the function isn't properly declared at all, that lack of
declaration makes it a syntax error (11.3.5p1 - T is not optional, and
is missing from this declaration) regardless of whether there's any
return statement.
 
In the particular case of main(), there's additional requirements.
6.6.1p2 specifies two different ways to declare main() that all
implementations are required to accept; implementations of C++ have no
obligation to accept any declarations for main() that don't match one of
those two forms. This declaration doesn't match either of them.
Jivanmukta <jivanmukkta@poczta.onet.pl>: Feb 11 04:24PM +0100

W dniu 09.02.2019 o 21:35, David Brown pisze:
 
 
> However, Python is absolutely fine for the purpose, and probably better
> than PHP - I only only suggested PHP because I thought perhaps you were
> already familiar with the language.
 
 
Thus I choose PHP. I didn't know that I can produce .exe from PHP.
Thanks.
David Brown <david.brown@hesbynett.no>: Feb 11 07:34PM +0100

On 11/02/2019 16:24, Jivanmukta wrote:
>> you were already familiar with the language.
 
> Thus I choose PHP. I didn't know that I can produce .exe from PHP.
> Thanks.
 
I don't know how you do it, but I expect it is possible in a similar way
to Python (where the Python runtime and libraries are packaged together
in one huge exe file). Alternatively, you can install PHP normally, and
just run the PHP files from the command line.
"Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com>: Feb 05 04:01PM -0800

>> "slow_semaphore" is very beneficial.
 
>> ;^)
 
> See here: https://www.reddit.com/r/cpp/comments/anhnw3/fast_semaphore/
 
Before I comment there, the fences in the fast_semaphore are exactly
what is needed. Period. We _cannot_ get rid if them. End of story. I
will provide more into later on today or tomorrow.
"Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com>: Feb 05 03:20PM -0800

> my blog entry about fast c++ semaphore implementation: http://blog.vorbrodt.me/?p=495
 
Thank you for your interest. The "fast_semaphore" algorithm has many
advantages over a traditional "slow_semaphore". Fwiw, Joe Seigh
developed this back on comp.programming.threads within one of my
discussions with him, many years ago. IIRC, around 2007. Damn, I am
getting older. The ability to skip a lot of calls into to the
"slow_semaphore" is very beneficial.
 
;^)
"Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com>: Feb 05 11:24PM -0800

> my blog entry about fast c++ semaphore implementation: http://blog.vorbrodt.me/?p=495
 
Fwiw, this is called a benaphore:
 
https://en.wikipedia.org/wiki/Futex#BENAPHORE
 
I am not sure if Joe Seigh helped invent it or not. He was working at
IBM in the 80's and 90's. Fwiw, here is a patent for an interesting
reference counting algorithm invented by Joe:
 
https://patents.google.com/patent/US5295262
"Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com>: Feb 05 04:07PM -0800

On 2/5/2019 4:01 PM, Chris M. Thomasson wrote:
 
> Before I comment there, the fences in the fast_semaphore are exactly
> what is needed. Period. We _cannot_ get rid if them. End of story. I
> will provide more into later on today or tomorrow.
 
Actually, this is a good example. If we remove any of the fences, or
even weaken them, then the algorithm does _not_ work at all! The fences
enforce the acquire/release relationship between the wait/post functions
where wait is acquire, and post is release. The code has the position of
the membars in the exact correct position. The release is _before_ we do
anything in post. The acquire is _after_ we do everything in wait. If
the position of the standalone fences is changed, then the algorithm
will bite the dust.
 
Joe Seighs excellent algorithm is 100% correct, and the implementation I
showed you is 100% correct, period.
 
Will go into more detail today or tomorrow.
"Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com>: Feb 05 04:17PM -0800

On 2/5/2019 4:07 PM, Chris M. Thomasson wrote:
 
> Joe Seighs excellent algorithm is 100% correct, and the implementation I
> showed you is 100% correct, period.
 
> Will go into more detail today or tomorrow.
 
Ahhh, the following interesting discussion might be of interest wrt the
standalone fences:
 
https://groups.google.com/d/topic/lock-free/A1nzcMBGRzU/discussion
(read all...)
 
Another reason why I like standalone fences is that we can place them in
the _exact_ places they need to be. The other style of fences are
directly integrated into the std::atomic operations themselves. However,
they can be limited wrt flexibility. Take the following code into
account: It flushes all of the nodes from an atomic stack in a single
atomic operation:
_____________________________
// try to flush all of our nodes
node* flush()
{
node* n = m_head.exchange(nullptr, mb_relaxed);
 
if (n)
{
mb_fence(mb_acquire);
}
 
return n;
}
_____________________________
 
Notice how this specialized 100% standard membar setup is _impossible_
to accomplish with the integrated membars? Standalone fences are what I
am basically used to working with way back on the SPARC.
Juha Nieminen <nospam@thanks.invalid>: Feb 05 09:35AM

> fine using your current code. However, the data returned is dubious
> because the mutex m_cs was not locked where you mutate m_count. If empty
> is called a lot, then this type of racy check might be perfectly fine.
 
Making the variable atomic only makes sure that reading and writing the
variable itself concurrently won't result in garbage values. However, it
doesn't protect from other types of race conditions that might happen.
For example, a routine might read the variable and see that the
container is not empty, when in reality it is; it's just that the
routine that emptied the container was just about to zero the size
variable when that other thread read it.
 
If the code needs to make sure it doesn't get incorrect information
from that function, it needs to use the same mutex, to make sure
it's not reading the variable while another thread is modifying
the data structure.
 
All this can add quite a lot of overhead, but that's the eternal dilemma
with multithreading. (A lot of research has been put into developing
lock-free data containers, but that's a very hard problem.)
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
"Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com>: Feb 05 04:23PM -0800

On 2/5/2019 1:35 AM, Juha Nieminen wrote:
>> is called a lot, then this type of racy check might be perfectly fine.
 
> Making the variable atomic only makes sure that reading and writing the
> variable itself concurrently won't result in garbage values.
 
It also prevents undefined behavior wrt a raw data-race.
 
 
> container is not empty, when in reality it is; it's just that the
> routine that emptied the container was just about to zero the size
> variable when that other thread read it.
 
Fair enough. Even if the empty condition returns a coherent answer, it
still unlocks the mutex. So, the next time we check it, the empty
condition might be different. Fwiw, I usually only use these types of
empty function calls for statistics. Just to see how many times the
queue is empty within a certain time frame. This type of data can be
used for heuristics to alter server state, build graphs or whatever...
 
 
David Brown <david.brown@hesbynett.no>: Feb 05 11:15AM +0100

On 05/02/2019 08:41, Bonita Montero wrote:
>> these data structures - ...
 
> No, these data-structures are in memory anyway.
> Just the link-node in the queue comes afterwards.
 
They will not be in memory if the producer has stopped producing!
Bonita Montero <Bonita.Montero@gmail.com>: Feb 05 08:41AM +0100

>> than a simple link-node in the queue.
 
> That means that the producer needs to use a lot more memory to make
> these data structures - ...
 
No, these data-structures are in memory anyway.
Just the link-node in the queue comes afterwards.
Bonita Montero <Bonita.Montero@gmail.com>: Feb 05 11:46AM +0100

>> No, these data-structures are in memory anyway.
>> Just the link-node in the queue comes afterwards.
 
> They will not be in memory if the producer has stopped producing!
 
Its plainly idiotic not to hand off items to another threads because
of memory-issues; if there isn't a memory-collapse that stops further
processing it makes always sense to hand of the items to the consumer.
And if there is a memory-collapse, this will just stop the processing
of an item. No one develops the producer in a way that it will build
different data-structures for processing in the producer if a queue
is full. And this short-circuited processing would be stupid also
because it wouls stop the producer from processing input from other
sources for a while.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 05 04:35PM +0100

On 05.02.2019 16:03, Juha Nieminen wrote:
>> Isn't it impractical to develop on a phone?
 
>> I don't like typing on my phone, an Android thing.
 
> Phone applications aren't developed on the phone itself.
 
But, then according the text I responded to, the developers are
"armchair mushrooms", and that can't be right either?
 
 
Cheers!
 
Alf (probably an armchair mushroom (at least he uses a chair, and every
time he sticks his head up it's cut off, just like a mushroom)).
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 05 02:56PM +0100

On 05.02.2019 14:01, Öö Tiib wrote:
> since desktops (and it doesn't matter if Windows,
> Linux or OS X) are for armchair mushrooms, alive
> people use handheld devices more than desktops.
 
Isn't it impractical to develop on a phone?
 
I don't like typing on my phone, an Android thing.
 
Not to mention text selection and text operations in general.
 
 
Cheers!,
 
- Alf
Juha Nieminen <nospam@thanks.invalid>: Feb 05 03:03PM

> Isn't it impractical to develop on a phone?
 
> I don't like typing on my phone, an Android thing.
 
Phone applications aren't developed on the phone itself.
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
Manfred <noname@add.invalid>: Feb 05 06:05PM +0100

On 2/5/2019 2:01 PM, Öö Tiib wrote:
> since desktops (and it doesn't matter if Windows,
> Linux or OS X) are for armchair mushrooms, alive
> people use handheld devices more than desktops.
 
Not me, when I walk down the street and I see all those droids walking
with their eyeballs fixed on their displays, "The Walking Dead" comes
immediately to mind.
Just another reply from an "armchair mushroom".
"Öö Tiib" <ootiib@hot.ee>: Feb 10 11:47PM -0800

On Friday, 8 February 2019 18:25:30 UTC+2, Marcel Mueller wrote:
 
> Hmm, not that pretty. Especially for open source software which may be
> compiled on quite different platforms, at least ones that I cannot test.
 
> For now I don't rely on constexpr, so I can live with the cast.
 
Most open source libraries go for such solutions quite frequently. The
platform vendors *love* to be as incompatible as possible and that
won't change.
Marcel Mueller <news.5.maazl@spamgourmet.org>: Feb 08 05:25PM +0100

Am 08.02.19 um 09:51 schrieb Öö Tiib:
> an hour to get majority covered. The only corner case is
> when you have zero-sized std::arrays (those are allowed to lack
> that member) but otherwise it is kind of piece of cake.
 
Hmm, not that pretty. Especially for open source software which may be
compiled on quite different platforms, at least ones that I cannot test.
 
For now I don't rely on constexpr, so I can live with the cast.
 
 
Marcel
"Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com>: Feb 07 11:43AM -0800

On 2/7/2019 3:43 AM, Sam wrote:
> operations that update m_signaled fail to notify the condition variable.
 
> Since the condition variable is used to wait for a change to m_signaled,
> all code paths that modify m_signaled should notify the condition variable.
 
Why would one need to notify the condition variable on a reset?
 
 
>>         m_cv.wait(lock, [&](){ return m_signaled; });
>>         if(reset) m_signaled = false;
>>     }
 
The wait wrt the reset parameter is fairly dangerous here. It allows one
to mix and match an auto-reset event with a manual-reset event. This is
not Kosher, and can lead to deadlock conditions. Creating two distinct
classes, auto-reset and manual-reset would help solve this issue.
 
 
>>         std::unique_lock<std::mutex> lock(m_mutex);
>>         m_signaled = false;
>>     }
 
No need to signal anything here, even though we mutated the predicate of
the condition variable.
 
 
David Brown <david.brown@hesbynett.no>: Feb 07 10:56PM +0100

On 07/02/2019 21:06, Alf P. Steinbach wrote:
> combinatorial explosion. Imagine 16 yes/no config options like
> `CPPX_ASCII_PLEASE` above. One would not want 65 536 library variants.
 
> So, what's the new way to do things?
 
Can it be done with "if constexpr (CPPX_ASCII_PLEASE) " ?
 
Can you have template constexpr variables?
 
Put them in a templated struct?
 
Have them both as two namespaces, and let the module user pick the
namespace they want?
 
Scrap all encodings except proper UTF-8 (which has no BOM)?
 
 
I don't know if any of these solutions are possible - I haven't looked
at modules in detail. But perhaps they will put you onto a solution
that would work.
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: