Saturday, September 22, 2018

Digest for comp.lang.c++@googlegroups.com - 21 updates in 6 topics

Horizon68 <horizon@horizon.com>: Sep 22 12:45PM -0700

Hello,
 
 
My scalable algorithm is coming soon..
 
 
I have just today enhanced "much" more my "invention" of a scalable
algorithms of a scalable reference counting with efficient support for
weak references, i think i am the only one who has invented this
scalable algorithms, because it is the only one who is suited for
non-garbage collecting languages such as C++ and Rust and Delphi, my
previous algorithms was not completely scalable, because the first
object that is reference counted was not scalable, but today i have just
made my algorithm "fully" scalable on manycores and multicores and NUMA
systems by using a clever scalable algorithms, so i think i will
"sell" my invention that is my scalable reference counting algorithm
with efficient support for weak references and its implementation to
Microsoft or to Google or to Intel or Embarcadero
 
 
I invite you also to listen to this beautiful song:
 
 
Eddy Grant - Gimme Hope Jo'Anna (1988)
 
https://www.youtube.com/watch?v=qFcmNu4KdGI
 
 
Thank you,
Amine Moulay Ramdane.
Sam <sam@email-scan.com>: Sep 22 02:18PM -0400

I'm looking for a way to make my linker tell me that the executable it
linked contains the same symbols as in one of the executable's shared
libraries. Apparently this links fine, and the global symbols from the
executable override the ones in the shared library, and not just for
references in the executable itself, but also any references in the shared
library. References to the duplicate symbols from other translation units in
the shared library end up getting bound to the executable at runtime, and
not to the duplicate in the shared library, and hilarity ensues.
 
I'm using the gold linker on Linux. A contrived example:
 
/*************************************************************************/
 
/* log.h */
 
struct somelog {
 
 
somelog();
~somelog();
};
 
/* log.C */
 
#include <iostream>
#include "log.H"
 
somelog::somelog()
{
std::cout << "Constructed " << this << std::endl;
}
 
somelog::~somelog()
{
std::cout << "Destroyed " << this << std::endl;
}
 
somelog default_log;
 
/* main.C: */
 
#include <iostream>
 
#include "log.C"
 
int main()
{
return 0;
}
 
/*************************************************************************/
 
Like I said, this is a very contrived example. But nothing apparently goes
wrong during compilation. With gcc 8.1.1 and the gold linker:
 
$ g++ -shared -o log.so -DPIC -fPIC log.C
$ g++ -o main main.C log.so -Wl,-R`pwd`
 
And the hilarious part:
 
$ ./main
Constructed 0x403061
Constructed 0x403061
Destroyed 0x403061
Destroyed 0x403061
 
I am using every paranoid/hardening/pedantic compilation option I am aware
of, but this slipped by undetected. Perusing ld's manual page doesn't find
anything useful. Perhaps there an option that I missed, that will warn me if
my executable will override any symbols in one of the shared libraries it
links with, directly. I suppose that it's not possible to do anything about
collisions from shared libraries that get linked indirectly, but it should
be possible to warn about directly-linked shared libs.
Bart <bc@freeuk.com>: Sep 22 12:45AM +0100

On 21/09/2018 23:00, Öö Tiib wrote:
> one-liners in C++11 and done. Nothing magical.
> Example that will work with operands of any types between what
> operator == that returns bool exists.
 
Implementing chained "==" would also work with any types for which "=="
is valid. And the same solution would work for "!=", as well as
"<","<=",">=", and ">", although those would be valid for fewer types.
 
> {
> return (t == u) && allEqual(u, std::forward<Ts>(args)...);
> }
 
(On rextester.com, this only worked with VC++, not gcc or clang where it
didn't like std::forward.
 
I don't know C++ enough to know what overheads (both compile-time and
run-time) such a solution involves and what disadvantages there are,
apart from having to do it.
 
And then being stuck with a small support library that now has to be
part of the code.)
 
> int hsample[4] = {42, 42, 42, 42};
> int vsample[4] = {0, 42, 42, 666};
> if (allEqual(hsample[1], vsample[1], hsample[2], vsample[2]))
 
I thought the problem was all the errors that could occur when you have
to enumerate all the terms one by one. This doesn't solve that. That
last term can still be written hsample[2].
 
Remember as written in the language of the original example (using
1-based) it would be:
 
if hsample[2] = vsample[2] = hsample[3] = vsample[3] then
 
 
--
bart
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Sep 22 02:44AM +0200

On 22.09.2018 00:00, Öö Tiib wrote:
> std::cout << "yes\n";
> }
> }
 
Not sure I like the recursion there. Also, I feel it should have
shortcut evaluation, a.k.a. "short-circuit evaluation". Like,
 
#include <array> // std::(array)
#include <functional> // std::(reference_wrapper)
#include <type_traits> // std::(common_type_t)
 
namespace my
{
using std::common_type_t, std::array, std::reference_wrapper;
 
inline auto all_equal() -> bool { return true; }
 
template< class... Items >
inline auto all_equal( const Items&... items )
-> bool
{
using Item = common_type_t< Items... >;
constexpr int n = sizeof...( items );
 
const array<reference_wrapper<const Item>, n> item_refs = {
items... };
for( int i = 1; i < n; ++i )
{
if( item_refs[i] != item_refs[0] ) { return false; }
}
return true;
}
}
 
#include <iostream>
using namespace std;
auto main()
-> int
{
const int hsample[] = { 42, 42, 42, 42 };
const int vsample[] = { 0, 42, 42, 666 };
 
if( my::all_equal( hsample[1], vsample[1], hsample[2],
vsample[2] ) )
{
cout << "yes" << endl;
}
}
 
 
Cheers!,
 
- Alf (in a non-recursive mood)
"Öö Tiib" <ootiib@hot.ee>: Sep 21 06:12PM -0700

On Saturday, 22 September 2018 02:45:19 UTC+3, Bart wrote:
> > }
 
> (On rextester.com, this only worked with VC++, not gcc or clang where it
> didn't like std::forward.
 
Oh. #include <utility> Also most common C++ headers like <iostream>
will cause it to be included as well.
 
 
> I thought the problem was all the errors that could occur when you have
> to enumerate all the terms one by one. This doesn't solve that. That
> last term can still be written hsample[2].
 
I do not know a tool that can figure out that we wrote something that
is valid but does not mean what we did want to write. We are often
distracted or preoccupied with other things so it happens daily. I just
write unit tests to double-check if my function results with what I did
mean it to result.
 
> Remember as written in the language of the original example (using
> 1-based) it would be:
 
> if hsample[2] = vsample[2] = hsample[3] = vsample[3] then
 
It will complain? When you write:
 
if hsample[2] = vsample[2] = hsample[3] = vsample[2] then
 
Why?
"Öö Tiib" <ootiib@hot.ee>: Sep 21 06:47PM -0700

On Saturday, 22 September 2018 03:49:20 UTC+3, Alf P. Steinbach wrote:
> > }
> > }
 
> Not sure I like the recursion there.
 
Is it because of you feel recursion harder to read? Compilers tend to
optimize above program to 'std::cout << "yes\n";' anyway.
Demo: https://godbolt.org/z/s8K7bB
We may need somewhat more tricky input data to see if there are any
disadvantages.
 
> cout << "yes" << endl;
> }
> }
 
Yes, compilers optimize that to 'std::cout << "yes" << std::endl;'
as well.
Joe Pfeiffer <pfeiffer@cs.nmsu.edu>: Sep 21 09:17PM -0600


> I regularly hear speakers on compute-related videos report
> that their scientists say there isn't a better language to
> express the formulas they use for calculation than in Fortran.
 
I'm a little surprised they don't prefer Mathematica since it does
*really* nicely with vector and matrix operations. But really, if
you're doing scalar equations Fortran is neither substantially better
nor worse than just about anything else out there. Yeah, a builtin
exponentiation operator is nice, as is builtin complex numbers (which C
also has), but they aren't a big deal.
 
> I've never used it personally. I play to support it with
> RDC though at some point.
 
Don't bother. Life is short; there isn't time to learn computer
languages unless there is something you want to use them for (the
closest I ever came to having a real job was being a student intern
at Weyerhaeuser, doing simulations and dynamic programming in Fortran.
It's a language. Nothing really special about it after all these
years).
David Brown <david.brown@hesbynett.no>: Sep 22 11:12AM +0200

On 22/09/18 01:45, Bart wrote:
 
> I don't know C++ enough to know what overheads (both compile-time and
> run-time) such a solution involves and what disadvantages there are,
> apart from having to do it.
 
These two give identical code with gcc:
 
bool check1(void) {
return hsample[1] == vsample[1] &&
vsample[1] == hsample[2] &&
hsample[2] == vsample[2];
}
 
bool check2(void) {
return allEqual(hsample[1], vsample[1], hsample[2], vsample[2]);
}
 
So no runtime overhead (as expected).
 
Templates like this don't normally have any run-time costs - nor do
things like std::forward or std::move that are just odd (for non C++
gurus) type manipulations. C++ uses some of that sort of function that
don't seem to actually /do/ anything, just pass data in and out with
different kinds of references or type variations added or removed. They
are mainly so that the right function gets called in the end, while
still retaining the type safety and type information.
David Brown <david.brown@hesbynett.no>: Sep 22 11:25AM +0200

On 22/09/18 03:12, Öö Tiib wrote:
> distracted or preoccupied with other things so it happens daily. I just
> write unit tests to double-check if my function results with what I did
> mean it to result.
 
PVS Studio (apparently) does a good of spotting copy-and-paste errors,
such as writing hsample[2] instead of vsample[2] at the end of the list.
 
For those on a lesser budget, gcc "-Wduplicated-cond" and
"-Wduplicated-branches" can sometimes help, but don't trigger here.
David Brown <david.brown@hesbynett.no>: Sep 22 11:32AM +0200

On 21/09/18 19:46, Keith Thompson wrote:
> propose.
 
> See also
> https://github.com/Keith-S-Thompson/fizzbuzz-c/blob/master/fizzbuzz093.c
 
The spaceship operator is not expected to find much use in user code
like this. The main idea is that if you want to make a class for
objects with comparison, you can define a single spaceship operator
function for it and get <, >, ==, !=, <= and >= generated automatically.
It is a labour (and therefore bug) saving device, rather than for
application code.
 
Of course, that doesn't mean you can't use it in switches like this.
"Öö Tiib" <ootiib@hot.ee>: Sep 22 05:12AM -0700

On Saturday, 22 September 2018 12:32:51 UTC+3, David Brown wrote:
> like this. The main idea is that if you want to make a class for
> objects with comparison, you can define a single spaceship operator
> function for it and get <, >, ==, !=, <= and >= generated automatically.
 
That is certainly one usage. But there can be others. I see two more
but haven't yet thought out proper policies:
 
1) Until spaceship checking incomparability is painful.
 
if (!(a == b) && !(a != b)) // anyone?
 
With spaceship it will be

switch (a <=> b)
{
case std::partial_order::unordered: // better?
 
I have met several cases when incomparability was possible but was
not checked or handled. That resulted with defects and even
security vulnerabilities. I hope that spaceship can make that more
transparent.
 
2) As rule the comparisons of composites are implemented by combining
comparisons of components. I hope that spaceship will make that process
less error-prone and resulting code more elegant (and may be even more
efficient).
 
There can be even more beneficial usages but I still perceive it as
complicated operator that is easy to misuse and hard to explain.
 
> It is a labour (and therefore bug) saving device, rather than for
> application code.
 
That is one reason of my dislike, it is most hard to define a line
between application code and what else there is.
David Brown <david.brown@hesbynett.no>: Sep 22 02:50PM +0200

On 22/09/18 14:12, Öö Tiib wrote:
 
> switch (a <=> b)
> {
> case std::partial_order::unordered: // better?
 
if (comparable(a, b)) ... // Much better
 
The spaceship operator may be a fine way to implement "comparable", but
I like names with meanings.
 
> not checked or handled. That resulted with defects and even
> security vulnerabilities. I hope that spaceship can make that more
> transparent.
 
Perhaps, but again I am not sure it would result in the most readable
code. (But it would be better than code that didn't do the necessary
checks.)
 
> efficient).
 
> There can be even more beneficial usages but I still perceive it as
> complicated operator that is easy to misuse and hard to explain.
 
Yes, that's why I expect it will have more use buried along with other
code that is hard to explain, rather than in application code.
 
>> application code.
 
> That is one reason of my dislike, it is most hard to define a line
> between application code and what else there is.
 
I'd say it is /impossible/ to define such a line, not just hard. That
doesn't mean the distinction can't be useful. (Imagine finding a line
between "light blue" and "dark blue" - you won't fine one. That won't
stop you describing something as "light blue" or "dark blue".)
 
I'd expect to see spaceships in more general code such as class and
template libraries, rather than in the application-specfic code that
uses these classes and functions.
"Öö Tiib" <ootiib@hot.ee>: Sep 22 07:10AM -0700

On Saturday, 22 September 2018 15:50:44 UTC+3, David Brown wrote:
 
> if (comparable(a, b)) ... // Much better
 
> The spaceship operator may be a fine way to implement "comparable", but
> I like names with meanings.
 
That is how to make it more elegant/readable. I was more about the core
issue. The "can of worms" when comparing polymorphic objects, optionals,
variants or floating point variables. You must have met related issues
too. With floating points there is additionally that "almost equal"/
"close enough" issue. The spaceship can help to notice, to explain and
to handle those issues in code.
 
 
> Perhaps, but again I am not sure it would result in the most readable
> code. (But it would be better than code that didn't do the necessary
> checks.)
 
Neither am I. What is fun about new things is to invent usages. Some of
those may become "idiomatic" later.
 
 
> I'd expect to see spaceships in more general code such as class and
> template libraries, rather than in the application-specfic code that
> uses these classes and functions.
 
I suspect that we will actually see it all over the code and coding
standards banning it and so on. It was so with three-way goto of
FORTRAN that received and keeps receiving major curses to this day.
People want to feel clever and I have no right to blame them since
I want sometimes to feel clever too. ;)
David Brown <david.brown@hesbynett.no>: Sep 22 04:36PM +0200

On 22/09/18 16:10, Öö Tiib wrote:
>> checks.)
 
> Neither am I. What is fun about new things is to invent usages. Some of
> those may become "idiomatic" later.
 
Fair enough ("fun" is a good enough reason for many things). I can only
hope that at least some of these idiomatic uses are legible :-)
 
 
> I suspect that we will actually see it all over the code and coding
> standards banning it and so on. It was so with three-way goto of
> FORTRAN that received and keeps receiving major curses to this day.
 
That sounds believable.
 
> People want to feel clever and I have no right to blame them since
> I want sometimes to feel clever too. ;)
 
No, it is okay to blame people for bad habits even when you have them
yourself. I want other people to write /better/ code than I do, not
merely as good code.
Sam <sam@email-scan.com>: Sep 22 01:19PM -0400

Keith Thompson writes:
 
> complications for floating-point operands. Using it with a switch
> statement would be similar to what you (sarcastically, I presume)
> propose.
 
Last time I checked, <=> is not required to return -1, 0, or 1, but a
negative value, zero, or a positive value, just like Perl.
 
This would preclude it from being useful in a switch, by itself.
Christian Gollwitzer <auriocus@gmx.de>: Sep 22 07:50PM +0200

> describe what it does. It's certainly not equivalent to either the
> current meaning of a < b < c, nor the proposed new meaning for that
> expression.
 
I think he wanted to mean it the proposed meaning with short circuiting
on the second comparison. For floating point, it would do this if the
"false" is replaced by either -Inf or NaN. *
 
OTOH this is so "tricky" that I would hide it in a macro or template,
and then we could simply use a more standard expression:
 
template <typename T>
bool in_range(T a, T x, T b) {
return (a < x) ? (x < b) : false
}
 
Christian
 
* I don't recall how to create thise special things from C++, why aren't
they accepted as floating point literals like this, instead of
std::mumble<ugly_template>::infinity() ?
"Öö Tiib" <ootiib@hot.ee>: Sep 22 11:14AM -0700

On Saturday, 22 September 2018 20:19:34 UTC+3, Sam wrote:
 
> Last time I checked, <=> is not required to return -1, 0, or 1, but a
> negative value, zero, or a positive value, just like Perl.
 
> This would preclude it from being useful in a switch, by itself.
 
With object pointers or integral types <=> will be most likely
required to return a value of type std::strong_ordering, with
floating point types std::partial_ordering and with function
pointers and pointer to member std::strong_equality.
Values of each of those types are likely discrete so useful with
switch. However what we talk about is C++20 so no one can predict
the future.
Tim Rentsch <txr@alumni.caltech.edu>: Sep 22 06:32AM -0700


> Note: the usual term was "unsigned preserving", correctly reflecting
> the fact that the rules were biased toward unsigned: they said that
> a + b must be unsigned if either a or b is unsigned.
 
My understanding is that the cases under discussion were only
those involving promotion of types narrower than int to one of
{int, unsigned int} - that is, what the Standard terms "integer
promotions". An unsigned int added to a long, for example, would
still be a signed type, not an unsigned type (assuming unsigned
int is narrower than long).
 
(The Rationale document also mentions the typing of integer
constants, but that has no bearing on the above remarks.)
Tim Rentsch <txr@alumni.caltech.edu>: Sep 22 05:08AM -0700

> <float.h>."
 
> However, that does not mean that it's required to document the
> sizes of those types. [...]
 
In C, the sizes of all types are implementation-defined (if not
explicitly specified).
 
C N1570 6.2.6.1 p2:
 
Except for bit-fields, objects are composed of contiguous
sequences of one or more bytes, the number, order, and
encoding of which are either explicitly specified or
implementation-defined.
 
C N1570 6.5.3.4 [sizeof and _Alignof operators] p5:
 
The value of the result of both operators is
implementation-defined, [...]
Tim Rentsch <txr@alumni.caltech.edu>: Sep 22 05:25AM -0700


> [.. are sizes, and/or ranges, of integer types specified
> as being implementation defined in C++? ..]
 
 
For ranges:
 
C N1570 section 5.2.4.2 p1:
 
An implementation is required to document all the limits
specified in this subclause, which are specified in the
headers <limits.h> and <float.h>. [...]
 
C++ N4762 section 16.3.5 p1:
 
The header <climits> defines all macros the same as the C
standard library header <limits.h>. [...]
 
 
For sizes:
 
C N1570 section 6.2.6.1 p2:
 
Except for bit-fields, objects are composed of contiguous
sequences of one or more bytes, the number, order, and
encoding of which are either explicitly specified or
implementation-defined.
 
C N1570 section 6.5.3.4 [sizeof and _Alignof operators] p5:
 
The value of the result of both operators is
implementation-defined, [...]
 
C++ N4762 section 7.6.2.3 p1:
 
[..corner cases such as bitfields or function types..]
The result of sizeof applied to any other fundamental type
(6.7.1) is implementation-defined. [...]
"Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid>: Sep 21 03:17PM -0700


> You're imagining the deck sitting on a surface? It can also be held in hand.
> Card sharps have no problem removing cards from either the top or the bottom
> of the deck, when dealing.
 
Excellent point. I am wondering the the following video just might be of
some sort of service to the OP:
 
https://youtu.be/B_aSqq2qAD4
 
Imvho, this guy is pretty darn slick... Imagine playing poker with a
blind person! :^)
 
 
>> Or is it thought that we have two stacks, which can be used to simulate a
>> dequeue?
 
> ... that's *deque*. "dequeue" is an operation (the opposite of "enqueue").
 
For the OP:
 
enqueue = adding elements to a container in FIFO order
 
dequeue = removing elements from a container in FIFO order
 
This FIFO order is sort of "implied" by the suffix "queue" as opposed to
the prefix "en" or "de".
 
For fun, enstack or destack wrt "stack" basically implies LIFO order.
 
;^)
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: