Tuesday, February 28, 2017

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

Louis Krupp <lkrupp@nospam.pssw.com.invalid>: Feb 27 09:44PM -0700


>using namespace std;
 
>// list external variables
>extern lapack_int n;
 
This variable 'n' has no connection with the variable 'n' defined in
the previous program.
 
>extern string outfilename;
 
Likewise for 'outfilename'.
 
> while (fin >> w){
> // create a variable which will become the largest eigenvalue
> float wLargest = w;
 
You say you want to set wLargest to the first value read, but you're
actually setting it for *every* value you read.
 
There are at least a couple of ways to fix this, and they all involve
declaring wLargest somewhere other than inside the loop. Suppose, for
example, you were computing the sum of the values you were reading.
Would you declared the sum variable inside the loop, or would you put
it somewhere else?
 
 
>For some reason, outfilename is not recognized even though I specified it as an extern.
 
>Second, the while loop isn't actually doing what I want. I want to set the wLargest initially to the first value that is read from the textfile. I only want to do this once. Next I will compare wLargest, and if the w read from the file is larger than wLargest, wLargest will be replaced by that value. Then, a new w is read. But the problem with the above is that when a new w is read, it replaces the w that wLargest was equal to from the previous iteration and I don't want that. But I don't know how to fix it.
 
>Any help would be much appreciated.
 
I remember learning to program. It was fun.
 
Louis
Manfred <mx2927@gmail.com>: Feb 28 11:29PM +0100

On 02/28/2017 05:44 AM, Louis Krupp wrote:
> actually setting it for *every* value you read.
 
> There are at least a couple of ways to fix this, and they all involve
> declaring wLargest somewhere other than inside the loop.
Well, there's at least one way that can work with wLargest declared as
it is, but with a different storage duration (storage class specifier).
This would make use of the fact that this function (main) will be
executed exactly once.
Robert Wessel <robertwessel2@yahoo.com>: Feb 24 01:19AM -0600

On 24 Feb 2017 02:58:43 GMT, ram@zedat.fu-berlin.de (Stefan Ram)
wrote:
 
> 1.4 seconds. And this was only in Firefox, Chrome might
> even be faster. Amazing what they can get out of
> interpreters today!
 
 
The better Javascript processors are JITs these days.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 24 05:26AM +0100

On 24.02.2017 01:33, Stefan Ram wrote:
> R = ::std::move( x );
> x = ::std::move( r );
> r = ::std::move( a ); }}
 
Oh. :)
 
I confirmed, by writing my own little program for that, that you get a
correct result. Although it is for index 999.999 in the sequence, when
one considers fib(0) = 1, fib(1) = 1, fib(2) = 2, fib(3) = 3 and so on.
 
I'm not sure how your code works, it seems to do strange things, but
here's the expressive C++ dialect code that I cooked up to test it and
show how I would have written that program:
 
 
[code]
#include <p/expressive/using_weakly_all.hpp>
 
#include <algorithm>
#include <iostream>
#include <math.h> // log
#include <vector>
using namespace std;
 
using Big_int = std::vector<int>; // Each item is a decimal digit.
 
$procedure add_to( ref_<Big_int> a, ref_<const Big_int> b )
{
$let size_a = n_items_in( a ); $let size_b = n_items_in( b );
$var carry = 0;
for( $each i $in i_up_to( max( size_a, size_b ) ) )
{
if( i >= size_a ) { a.resize( i + 1 ); }
a[i] += carry + ($when( i < size_b ) $use( b[i] ) $default_to(
0 ));
carry = a[i]/10;
a[i] -= 10*carry;
}
if( carry != 0 ) { a.push_back( carry ); }
}
 
$just
{
$let golden_ratio = 1.6180339887498948482045868343656;
$let n = 100'000;
$let n_digits = static_cast<int>( (n + 10)*log10( golden_ratio ) + 1 );
clog << n_digits << " digits expected.\n";
 
$var a = Big_int{1}; a.reserve( n_digits );
$var b = Big_int{0}; b.reserve( n_digits );
for( $n_times( n ) )
{
$var next = a;
add_to( next, b );
a = move( b ); b = move( next );
}
for( $each digit $in reverse_span_of( b ) ) { cout << digit; }
cout << endl;
}
[/code]
 
I did not take the trouble to split the addition loop into parts where
the processing could be specialized for speed; I just used `-O3`. ;-)
 
This might be the reason that this code is shorter, 43 versus 91 lines,
even though my code looks much more verbose and whitespacey-ish.
 
 
Cheers!,
 
- Alf
 
PS: One problem with the $n_times macro is that g++ produces a very much
undesired warning "-Wno-unused-but-set-variable". I just turn it off but
I would like to suppress it for this situation in the code. I tried with
`_Pragma` expressions in the macro but g++ would have none of that
inside a `for` loop head. The macro is currently defined as
`$e::Dummy_reference_consumer $unique_temp_name $in $e::i_up_to( n )`. I
can't think of a way to do that without a range based loop.
Daniel <danielaparker@gmail.com>: Feb 28 11:30AM -0800

On Tuesday, February 28, 2017 at 5:58:52 AM UTC-5, Alf P. Steinbach wrote:
 
> Ben answered: "Of what practical use is a newborn baby?""
 
Hmmm ... it seems to me that that quote would be more apropos if you were
inventing a new programming language, or such. Of course, anyone willing to
work for free can do anything that they like. But did you have to work on this!
 
:-) Be well,
Daniel
Juha Nieminen <nospam@thanks.invalid>: Feb 28 02:26PM

Consider something like this:
 
template<typename> int foo() { return 1; }
template<> int foo<unsigned>() { return 2; }
 
If this is included in more than one compilation unit, does the latter
function need to be explicitly declared 'inline'?
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 28 04:47PM +0100

On 2/28/2017 3:26 PM, Juha Nieminen wrote:
> template<> int foo<unsigned>() { return 2; }
 
> If this is included in more than one compilation unit, does the latter
> function need to be explicitly declared 'inline'?
 
Yes.
 
But you should be able to use that complete specialization just like an
ordinary function, with definition in one translation unit,
 
template<> int foo<unsigned>() { return 2; }
 
and just declaration in other translation units,
 
template<> int foo<unsigned>();
 
Disclaimer: I haven't tested that, and the ways of Bjarne are sometimes
mysterious.
 
 
Cheers!,
 
- Alf
Paavo Helde <myfirstname@osa.pri.ee>: Feb 28 08:25PM +0200

On 28.02.2017 17:47, Alf P. Steinbach wrote:
 
> template<> int foo<unsigned>() { return 2; }
 
> and just declaration in other translation units,
 
> template<> int foo<unsigned>();
 
In that case you need an explicit instantiation in the translation unit
containing the definition:
 
14/6: "A function template, member function of a class template,
variable template, or static data member of a class template shall be
defined in every translation unit in which it is implicitly instantiated
(14.7.1) unless the corresponding specialization is explicitly
instantiated (14.7.2) in some translation unit; no diagnostic is required."
 
It appears though that most implementations do not require the explicit
instantiation and appear to work fine without it (and with "no
diagnostic produced"). See the recent thread "does the language
guarantee `explicit specialization' will generate the code ?".
woodbrian77@gmail.com: Feb 28 08:46AM -0800

On Thursday, February 16, 2017 at 11:24:37 PM UTC-6, Rick C. Hodgin wrote:
> continue to be impressed with each new release. (Note: I have no
> affiliation with Atlassian, except that I used Stash and Bitbucket).
 
> https://www.atlassian.com/software/bitbucket
 
Thanks. Looks interesting. In retrospect, I wish
someone would have suggested Atlassian or Github to
me years ago. I'm enjoying using them.
 
Until recently I had one directory where I built both
a library and two executables (tiers). Now I've added
a new directory called "tiers" and moved the code for
the tiers there. I think this will help people who
are interested in learning to use my software.
 
The downside to this is I'm specifying CXX and CXXFLAGS
(and maybe a few other things like that) in multiple
makefiles. I figured out a way where I could pass those
from the higher level makefile to the lower level --
something like:
 
$(MAKE) -C tiers CXX=$(CXX) CXXFLAGS=$(CXXFLAGS)
 
. But then I realized that would only work from the
top level directory. If I ran make from the tiers
subdirectory, it wouldn't work. So I did the obligatory
search for alternatives to make. Then I got a little
discouraged, and decided to stick with make.
 
 
This is my top level makefile
https://github.com/Ebenezer-group/onwards/blob/master/makefile
 
And this is a lower level makefile
https://github.com/Ebenezer-group/onwards/blob/master/tiers/makefile
 
Thanks in advance for suggestions on how to improve those files.
 
 
Brian
Ebenezer Enterprises - So far G-d has helped us.
http://webEbenezer.net
scott@slp53.sl.home (Scott Lurndal): Feb 28 05:11PM

>from the higher level makefile to the lower level --
>something like:
 
>$(MAKE) -C tiers CXX=$(CXX) CXXFLAGS=$(CXXFLAGS)
 
A common solution for this is to encapsulate your
definitions in a file at the top level called
Makefile.defs.
 
Encapsulate your rules in a top-level file called Makefile.rules.
e.g:
 
Makefile.defs:
--------------
CINCLUDES = -I$(TOP)/include
CINCLUDES += -I$(TOP)
 
DEBUGFLAGS = -g
 
GXXFLAGS = -mno-red-zone
GXXFLAGS += -fno-strict-aliasing
GXXFLAGS += -fno-stack-protector
GXXFLAGS += -fno-exceptions
GXXFLAGS += -Wall
GXXFLAGS += -mtune=native
GXXFLAGS += -O2
 
CXXFLAGS = $(DEBUGFLAGS) $(CINCLUDES) $(strip $(GXXFLAGS))
 
LDFLAGS += -Wl,-E
SOLDFLAGS += -Wl,-E -shared -lpthread -nostartfiles -nodefaultlibs -nostdlib
LIB = $(TOP)/lib
 
LIBCOMMON = $(LIB)/libcommon.a
LIBPROCESSOR = $(LIB)/libprocessor.a
LIBMP = $(LIB)/libmp.a
LIBDIRECTIVE = $(LIB)/libdirective.a
LIBOP = $(LIB)/libop.a
SIM_LIBS = $(LIBMP)
SIM_LIBS += $(LIBPROCESSOR)
SIM_LIBS += $(LIBCOMMON)
SIM_LIBS += $(LIBFETCH)
 
Makefile.rules:
---------------
#
# Common Makefile Rules
#
%.o: %.c
@echo " COMPILE $<"
$(HUSHCOMPILE)$(CC) $(CFLAGS) -MMD -o $@ -c $<
 
%.o: %.cpp
@echo " COMPILE $<"
$(HUSHCOMPILE)$(COMPILE.cpp) -MMD -o $@ $<
 
%.s: %.cpp
@echo " COMPILE-TO-ASM $<"
$(HUSHCOMPILE)$(COMPILE.cpp) -MMD -S $<
 
%.so: %.o
@echo " BUILDSO $@"
$(HUSHCOMPILE)$(LD) -o $@ $(SOLDFLAGS)
 
%.icm5: %.sprasm
@echo " SPRASM $<"
$(HUSHCOMPILE)$(SPRASM) $(SPRASM_FLAGS) -o $@ $<
 
buildsubs:: $(DIRS) subdirs
 
clean:: subdirs
.PHONY: subdirs clean $(SUBDIRS)
clobber:: clean subdirs
 
subdirs: $(SUBDIRS)
 
$(SUBDIRS):
@ $(MAKE) -C $@ $(MAKECMDGOALS) $(MAKEARGS)
 
clean::
@-$(RM) -f $(CLEAN_FILES) $(OBJECTS)
@ if [ -n "$(CLEAN_DIRS)" ]; then \
$(RM) -rf $(CLEAN_DIRS); \
fi
 
Then the top-level makefile:
 
Makefile:
---------
TOP=.
include $(TOP)/Makefile.defs
 
TARGET = vsim
 
SUBDIRS += common
SUBDIRS += io/dlps
SUBDIRS += processor
SUBDIRS += mp
SUBDIRS += utilities
 
SOURCES = main.cpp
OBJECTS = $(SOURCES:.cpp=.o)
 
HOST_LIBS = -lreadline -lcurses -lpthread -lgmp -ldl
 
DIRS = lib
 
CLOBBER_FILES += $(TARGET) $(TARGET).csc $(TARGET).csc.in $(TARGET).csc.po
CLOBBER_FILES += include/built.h
CLOBBER_DIRS += $(DIRS)
 
all: $(TARGET)
 
main.cpp: vsim_built buildsubs
 
utilities: common
 
$(SIM_LIBS): $(SUBDIRS)
 
$(TARGET):: $(OBJECTS) $(SUBDIRS) $(SIM_LIBS)
$(CXX) $(DEBUGFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(SIM_LIBS) $(HOST_LIBS)
$(OBJCOPY) --only-keep-debug $@ $@.debuginfo
$(OBJCOPY) --strip-debug $@
$(OBJCOPY) --add-gnu-debuglink=$@.debuginfo $@
 
include $(TOP)/Makefile.rules
-include *.d
 
common/Makefile:
----------------
TOP=..
include $(TOP)/Makefile.defs
 
SOURCES = command_table.cpp
SOURCES += contention_protocol.cpp
SOURCES += dcp.cpp
SOURCES += dcp_header.cpp
SOURCES += disassembler.cpp
SOURCES += ebcdic.cpp
SOURCES += file_logger.cpp
SOURCES += mcs.cpp
SOURCES += mux_logger.cpp
SOURCES += netport.cpp
SOURCES += osdep.cpp
SOURCES += pollselect.cpp
SOURCES += pool.cpp
SOURCES += protocol.cpp
SOURCES += serialport.cpp
SOURCES += station.cpp
SOURCES += syslog_logger.cpp
SOURCES += thread.cpp
SOURCES += timer.cpp
SOURCES += timer_manager.cpp
 
CXXFLAGS += -fpic
 
OBJECTS = $(SOURCES:.cpp=.o)
 
all: $(LIBCOMMON)
 
 
$(LIBCOMMON): $(OBJECTS)
ar cr $@ $+
 
include $(TOP)/Makefile.rules
 
---------
 
This will automatically descend into any directory
listed in SUBDIRS at each level and
build the Makefile in that subdirectory using the
common definitions in $(TOP)/Makefile.defs and $(TOP)/Makefile.rules
 
Objects from each subdirectory are archived in a archive
library specific to each subdirectory (since when using
parallel make, the 'ar' command isn't "parallel make" safe.
ram@zedat.fu-berlin.de (Stefan Ram): Feb 24 01:09AM

>>Java/C# have quite same roots but Java/Javascript? Nonsense connection.
>Using aggressive wording like »Nonsense« will not help
>to cover your lack of expertise.
 
Now I made the error that I dislike so much when I read it!
 
An article (determiner) is missing in front of »aggressive
wording«, but actually I intended to write the plural
»aggressive wordings«, and the »s« somehow disappeared.
ram@zedat.fu-berlin.de (Stefan Ram): Feb 24 02:58AM

>I did not really try to find the bug in your code, but I
>wrote a C++ program to print the 100'000th Fibonacci number.
 
I wrote a similar program in JavaScript:
 
Turns out: Here the JavaScript program is not much
slower than the compiled C++ program. The C++ program
takes about 1 second here and the JavaScript program about
1.4 seconds. And this was only in Firefox, Chrome might
even be faster. Amazing what they can get out of
interpreters today!
 
{ const alpha = new Date().getTime();
const fib =
( () =>
{ "use strict";
const e = 14;
const b = eval( "1e" + e );
const f = Array( e ).join( "0" );
let x = new Float64Array( 3e4 ); x[ 0 ] = 1.0; let xl = 1;
let r = new Float64Array( 3e4 ); r[ 0 ] = 1.0; let rl = 1;
let R = new Float64Array( 3e4 ); let Rl = 0;
let j = new Array( 3e4 );
let s = 0;
let a; let al;
let o = 0;
let p = 0;
let g; let G;
let h; let H;
const fibonacci =( n )=>
{ for( let i = 1; i < n - 1; ++i )
{ if( rl < xl ){ g = r; G = rl; h = x; H = xl; }
else { g = x; G = xl; h = r; H = rl; }
p = 0; o = 0;
while(p<G){s=o+g[p]+h[p];R[p++]=(s-(o=+(s>b))*b);}
while(p<H){s=o+h[p];R[p++]=(s-(o=+(s>b))*b);}
if(o!=0){s=o;R[p++]=(s-(o=+(s>b))*b);}
Rl = p;
a = R; al = Rl; R = x; Rl = xl; x = r; xl = rl; r = a; rl = al; }
let i = 0;
for( ; i < al - 1; ++i )j[ i ]=( f +( a[ i ] )).slice( -e );
j[ i ]= a[ i ];
return j.slice( 0, al ); }
return fibonacci( 100000 ).reverse().join( "" ); } )()
const omega = new Date().getTime();
console.log( fib );
console.log( omega - alpha ); }
ram@zedat.fu-berlin.de (Stefan Ram): Feb 24 03:08AM

>Turns out: Here the JavaScript program is not much
>slower than the compiled C++ program. The C++ program
 
When I use »double« for a bignum digit, I can store
14 decimal digits in one bignum digit with C++, and
then the program is about 10 % faster.
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.

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

ram@zedat.fu-berlin.de (Stefan Ram): Feb 24 12:33AM

>I decided to do a little challenge we used to give to the students in
>Bodø in the mid 1990s: to implement a bignumber class and use it to
>compute the Fibonacci sequence up to a ridiculous length.
 
I did not really try to find the bug in your code, but I
wrote a C++ program to print the 100'000th Fibonacci number.
 
Disclaimer: it's a quick hack: One cannot really change the
»< long, 1'000'000'000L >« below to something else, unless
on also edits the »"000000000"« in »to_string«.
 
Disclaimer: Code was slightly edited between the last test
and the post, hope not to introduce new bugs.
 
#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdlib>
#include <initializer_list>
#include <iostream>
#include <ostream>
#include <string>
 
using namespace ::std::literals;
 
/* a vector that will grow on demand */
template< typename T >
class vector : public ::std::vector< T >
{ public: using ::std::vector< T >::vector;
 
/* delete the following function definition when your estimates for
the number of digits in main are surely large enough (to trade some
security for speed) */
T& operator[]( typename vector::size_type const i )
{ while( i >= this->size() )this->push_back( 0 );
return( *( static_cast< ::std::vector< T >* >( this )))[ i ]; }};
 
/* a big number */
/* base must be less than MAX_DIGIT/2, say less than MAX_DIGIT/2-2,
base must be a power of 10 for the simplistic to_string function
below to be correct. */
template< typename DIGIT, DIGIT base >
class bignum : public vector< DIGIT >
{ public: public: using vector< DIGIT >::vector;
using digit_type = DIGIT;
typename ::bignum<DIGIT,base>::size_type length;
 
/* add h to g giving R,
h must not be shorter than g,
R is the result */
static void sum
( ::bignum<DIGIT,base> & g, ::bignum<DIGIT,base> & h,
::bignum<DIGIT,base> & R )
{ typename ::bignum<DIGIT,base>::size_type p = 0;
bool o = false; /* actually the carry bit */
while( p < g.length )
{ DIGIT const s = o + g[ p ]+ h[ p ];
R[ p++ ]= s -( o = s > base )* base; }
while( p < h.length )
{ DIGIT const s = o + h[ p ];
R[ p++ ]= s -( o = s > base )* base ; }
if( o )
{ DIGIT const s = o;
R[ p++ ]= s -( o = s > base )*base; }
R.length = p; }
 
static ::std::string to_string( ::bignum<DIGIT,base> & n )
{ ::std::string result; result.reserve( 1000 );
for( int i = n.length; i > 0; )
{ --i;
if( i == n.length - 1 )result += ::std::to_string( n[ i ]);
else
{ ::std::string s = ::std::to_string( n[ i ]);
char const * p = "000000000" + s.length();
result += p; result += s; }}
return result; }
 
/* set the argument to the number one */
static void one( ::bignum<DIGIT,base> & x )
{ x[ 0 ]= 1; x.length = 1; }};
 
int main()
{ using number = bignum< long, 1'000'000'000L >;
number x( 30'000 ); number::one( x );
number r( 30'000 ); number::one( r );
number R( 30'000 ); number::one( R );
number a;
for( long i = 2; i <= 100'000; ++i )
{
bool print = i == 100'000; /* edit here to specify which values */
/* you want to be printed. */
if( print )
{ ::std::string result = number::to_string( r );
::std::cout << i << ' ' << result << '\n'; ::std::cout.flush(); }
if( r.length < x.length )number::sum( r, x, R );
else number::sum( x, r, R );
a = ::std::move( R );
R = ::std::move( x );
x = ::std::move( r );
r = ::std::move( a ); }}
ram@zedat.fu-berlin.de (Stefan Ram): Feb 24 12:52AM

>Java/C# have quite same roots but Java/Javascript? Nonsense connection.
 
Using aggressive wording like »Nonsense« will not help
to cover your lack of expertise.
 
»The diktat from upper engineering management was that
the language must "look like Java"«. - Brendan Eich
ram@zedat.fu-berlin.de (Stefan Ram): Feb 25 06:14PM

> As once before, I recommend to either
> o use traditional comments or
> o use a Newsreader that will not break long lines or
 
I mean: on sending (posting) to the news server
 
> o to limit the line length so that the lines are not
> wrapped by the Newsreader.
 
on sending
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 25 01:38AM +0100

On 25.02.2017 01:01, Öö Tiib wrote:
> task and then the task can be given to other thread to solve.
> However if copy was lazy (with CoW) then we now either have race conditions
> of naive CoW or inefficiency of non-naive CoW.
 
To be clear, the situation you envision is that in thread B there is
 
const Cow_string sb = ...
 
initialized as a copy of tread A's
 
Cow_string sa = ...
 
Then when thread A modifies its `sa` it will have to stop the shared
buffer ownership, which modifies some reference counter or whatever
that's shared with `sb`, and might be concurrently accessed by B.
 
But this is only problem with an incorrect COW implementation, because
the cost of ensuring atomicity of the reference counting is miniscule,
completely insignificant, compared to the cost of copying the data,
which is the other part of that un-sharing-of-buffer operation.
 
 
 
> We can't if the CoW is done behind scenes. Then that means locks at
> wrong level of granularity inside of string AND locks outside as well
> if we really plan to use same string from multiple threads concurrently.
 
I think we can.
 
Yes it involves atomic operations or locking for the reference counting.
That's IMHO at the right level. It doesn't make the class generally
thread safe, which I see as an impractical goal (and on the way to
discovering how impractical, introducing awesome inefficiency), but it
makes it just thread safe enough to allow simple logical copying over to
another thread, without having to explicitly clone the object or check
its reference count – which is of course another option, to just be
completely explicit instead of relying on implicit, but then in a very
non-ideal way "leaking implementation details".
 
 
Cheers!,
 
- Alf (expressive, so far without gibberish diagnostics, yay!)
Juha Nieminen <nospam@thanks.invalid>: Feb 28 01:56PM

> cow(T const& x) : ptr(std::make_shared<T>(x)) {}
> cow(T && x) : ptr(std::make_shared<T>(std::forward<T>(x))) {}
 
I thought those were generated automatically by the compiler, unless
you disable them either explicitly (with =delete) or implicitly
(by implementing one but not the other, or implementing a copy or
assignment operator, or a destructor.)
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 25 06:23PM

On 25/02/2017 02:22, Alf P. Steinbach wrote:
 
> So, my attempt at breaking it failed, which I'm happy about. Also, that
> I identified a big hole in my understanding, that I could ask about. But
> is there still some way to break this code?
 
Why do you insist on obfuscating your C++ code with all these fucktarded
macros? You need to relearn writing C++ code without the use of macros.
 
/Flibble
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 23 09:38PM +0100

On 23.02.2017 15:42, Ben Bacarisse wrote:
 
> which differ from you decimal value of 14028385100242989008475377 by
> 18446744073709551616 which is 2^64. I.e. it's not just the last digit
> (the hex value is correct).
 
Thank you that clarified things for me.
 
 
>> first 121 Fibonacci numbers, and (2) the asserts don't trigger.
 
> Maybe there is some carry propagation error where the addition in the
> assert cancels the error from the subtraction.
 
Yes, that sounds very likely.
 
 
> Do you subtract by adding and fiddling the signs?
 
Yes. I was lazy, didn't want to deal with carry.
 
inline $procedure Big_int::operator-=( ref_<const Big_int> other )
{
if( is_positive() != other.is_positive() )
{
$self += -other;
return;
}
 
$let n_digits_this = n_items_in( digits_ );
$let n_digits_other = n_items_in( other.digits_ );
$let n_operand_digits = max( n_digits_this, n_digits_other );
 
digits_.reserve( n_operand_digits + 1 );
 
// The following performs subtraction of the magnitudes. If
this produces
// a negative magnitude, then the original sign is flipped.
 
// Add ((a big power of R) - other), where R, the radix of the
numeral
// system used for digits_, is the number of possible digit values.
$let big_minus_one_minus_other = other.complemented_wrt(
n_operand_digits );
add( big_minus_one_minus_other, 1 );
 
// Subtract the big power of R that was added.
if( n_items_in( digits_ ) > n_operand_digits )
{
// The magnitude result is positive or 0.
assert( digits_.back() == 1 );
digits_.resize( n_operand_digits );
}
else
{
// The magnitude result is negative, but is brought to
positive by the
// big power of R.
 
// Compute (big - this), pretending to be positive for the
increment:
$let real_sign = exchange( is_negative_, false );
complement_wrt( n_operand_digits );
add( 1 );
// And then compute (this - big) =
is_negative_ = not real_sign;
}
remove_leading_zeroes();
}
 
The bignum state is a vector `digits_` and a boolean `is_negative_`, and
the representation is sign-and-magnitude, with zero as an empty vector
and `is_negative_` set to `false`.
 
`exchange` here is `std::exchange`. I learned about it just some months
back, so I feel that not every reader would be familiar with it.
 
I feel sure that your informed hunch is in the right direction, and it
should have nailed it down, but I still don't see where I go wrong...
 
 
Cheers!, and thanks,
 
- ALf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 23 09:22PM +0100

On 23.02.2017 18:57, Mr Flibble wrote:
 
> All this $let_mutable and such bollocks makes your code harder to grok
> than standard C++ so I have no interest in examining it and therefore
> answering your questions about it.
 
Thanks, I think you're right about `$let_mutable`: it's too verbose by far.
 
The `$let` pseudo-keyword is shorter than the `auto const` that it
translates to, but `$let_mutable` is much longer than `auto`, just to
sort of press it into the same conceptual fold. It's idealism. Ungood.
 
I'm changing it to just `$var`, which is the conventional keyword for a
variable in JavaScript and C#.
 
#include <p/expressive/using_weakly_all.hpp>
 
#include <p/cppx/value_types/Big_int.hpp>
$using_nested_namespace( progrock, cppx );
 
#include <iostream>
$using_weakly_all_from_ns( std );
 
$procedure show_fibonacci()
{
using cppx::Big_int;
 
$var a = Big_int{ 1 };
$var b = Big_int{ 0 };
$var last_digit_of_a = 1;
$var last_digit_of_b = 0;
 
for( $each i $in i_up_to( 123 ) )
{
$let next = a + b;
$let s = next.to_decimal();
$let last_digit_of_next = s.back() - '0';
 
cout << i << " - " << s << " or in hex: " << next.to_hex()
<< endl;
$hopefully( last_digit_of_next == (last_digit_of_a +
last_digit_of_b) % 10 )
or $fail( "Ooops, that last result had incorrect last
decimal digit..." );
a = b; b = next;
last_digit_of_a = last_digit_of_b; last_digit_of_b =
last_digit_of_next;
}
}
 
$just{ show_fibonacci(); }
 
Cheers!, & thanks,
 
- Alf
Ben Bacarisse <ben.usenet@bsb.me.uk>: Feb 23 02:42PM

> 121 - 14028385100242989008475377 or in hex: B9A9F47B51D498BF6D4F1
 
> ! show_fibonacci - Ooops, that last result had incorrect last
> decimal digit...
 
Not sure what all the $stuff is, but
 
fib(121) = 14028366653498915298923761
 
which differ from you decimal value of 14028385100242989008475377 by
18446744073709551616 which is 2^64. I.e. it's not just the last digit
(the hex value is correct).
 
> 32-bit digits, and when the decimal presentation is /translated back/
> to hex it's correct except for the least significant hex digit of the
> most significant 32-bit digit, which hex digit is 2 too large...
 
I didn't follow this.
 
> }
 
> I can't see anything wrong, and (1) everything works just fine for the
> first 121 Fibonacci numbers, and (2) the asserts don't trigger.
 
Maybe there is some carry propagation error where the addition in the
assert cancels the error from the subtraction. Do you subtract by
adding and fiddling the signs?
 
<snip>
--
Ben.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 26 01:50AM +0100

On 24.02.2017 21:08, Tim Rentsch wrote:
> stuff. To look at any code more than about 10 or 20
> lines I would like to be able to compile it. If the
> code is written in "expressive" C++ I can't do that.
 
I've posted the current version of Expressive C++ on GitHub:
 
<url: https://github.com/alf-p-steinbach/Expressive-Cpp>
 
It uses a really tiny macro library, Macro Magic, that I also posted:
 
<url: https://github.com/alf-p-steinbach/Macro-Magic/>
 
Both libraries are header only and designed to be placed in a common `p`
directory in the compiler's include path. `p` is my middle name
shortened to one letter, and it's also short for "progrock".
 
Not sure exactly where to take this but it fills my free time.
 
And considering that you offered (if memory serves me!), I would be very
grateful if you could take over the balanced tree tutorial.
 
Another reason for that, if you have time, is that you evidently are
familiar with the subject, knowing stuff that I didn't know. ;-)
 
 
Cheers!,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 24 03:16AM +0100

On 24.02.2017 02:18, Mr Flibble wrote:
> Apart from yourself who are you trying to convince? Really bad.
 
I replied because you asked. Now you quoted everything just to point out
that you can't remember asking, and you wonder who. That's dumb.
 
Cheers!,
 
- Alf
Steve Keller <keller@no.invalid>: Feb 25 01:10AM +0100

> return arg + 1; // ambiguity! is this the local parameter
> // or the arg() function from <complex.h>?
> }
 
Yes, of course. But since in my code the call to exec(s) with Stmt *s
doesn't match the definition of FooStmt::exec() I wouldn't count this
as a match and continue matching in a wider scope and would find the
actually matching global exec(const Stmt *).
 
> s.exec();
> }
> };
 
Hm, this looks like an interesting solution. I'll consider this. But
for consistency I'd have to do it for class Expr {} with Expr::eval()
also, although I don't have the same problem there. What I dislike a
little is that in s.exec() the member s doesn't really look like a
pointer anymore.
 
Steve
Paavo Helde <myfirstname@osa.pri.ee>: Feb 24 08:53PM +0200

On 24.02.2017 19:52, Steve Keller wrote:
> have a number of occurrences of code like the following:
 
> class FooStmt : public Stmt {
> Stmt *s;
 
I assume you have taken care to consider why you can and need to use a
raw pointer here instead of some standard smart pointer.
 
 
> finds one (in this case the exec() member function without parameters)
> it does not continue to look for a matching exec(const Stmt *) outside
> of FooStmt. But why does is behave that way?
 
It's a general rule in C++ to use the matching identifier from the
closest scope (class scope in this case). Otherwise you could not write
things like
 
#include <complex.h>
 
int foo(int arg) {
return arg + 1; // ambiguity! is this the local parameter
// or the arg() function from <complex.h>?
}
 
 
> I don't like any of these solutions because a) makes the wrapper
> visible in the header file and b) and c) look cumbersome.
 
Basically you want to have a special kind of pointer where dereferencing
null is ignored. In C++ one writes a new class for such things:
 
class ExecPtr {
const Stmt* s;
// ...
public:
void exec() const {
if (s) {
s->exec();
}
}
};
 
class FooStmt : public Stmt {
ExecPtr s;
public:
virtual void exec() const {
s.exec();
}
};
Paavo Helde <myfirstname@osa.pri.ee>: Feb 25 05:20PM +0200

On 25.02.2017 17:16, Paavo Helde wrote:
> accidentally works without explicit specialization
 
s/specialization/instantiation/
 
my head starts aching ... ;-)
Ben Bacarisse <ben.usenet@bsb.me.uk>: Feb 24 08:09PM

thebtc@hotmail.com writes:
I'll make a few more remarks...
 
> {2, 10, 6, 1, 10, 5, 7, 1, 10, 5},
> {11, 0, 10, 8, 0, 11, 2, 7, 5, 1}
> }; // the symmetric matrix a for which the eigenvalues will be found
 
C++ does not permit this sort of array. The size of a plain array must
be a compile-time constant and, despite is being obvious to you, n is
not a compile-time constant. Writing
 
float a[10][10]
 
would be fine, as would
 
float a[][] = { { ... }, { ... }, ... { ... } };
 
where the compiler will deduce that the size is 10x10.
 
> fout << "eigenvalues of matrix A" << endl;
> LAPACKE_ssyev(&jobz, &uplo, &n, a, &lda, &w);
> fout.close();
 
This needs to go into main. But then you will find other problems.
Firstly, you are not passing enough arguments to LAPACKE_ssyev and the
ones you are passing are of the wrong type. In general, you won't need
any of those &s. In fact, you don't need many of those variables -- you
can pass 'N' and 'U' directly rather than by putting them into jobz and
uplo.
 
<snip>
--
Ben.
Paavo Helde <myfirstname@osa.pri.ee>: Feb 26 01:09AM +0200

> "/tmp/ccA0hQz3.o: In function `main':
> eigen.cc:(.text+0x97): undefined reference to `LAPACKE_ssyev'
> collect2: error: ld returned 1 exit status"
 
This is a linker error, not compiler error. This is good since it shows
that your code actually compiled and now you are stuck at the next
level, linking.
 
Most probably the problem is that you have not instructed your compiler
to actually link with the lapack library. You need to add correct -L and
-l options to your compiler command-line for specifying the directory of
the lapack library and its name, or specify them indirectly via some
menus and dialogs if you are using some kind of IDE.
 
The details depend a lot on which build system you use. The final
options passed to the linker (via compiler command-line) should look
something like
 
g++ ...other..options... -L/usr/local/lib -llapack
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Feb 20 06:32PM

On Mon, 20 Feb 2017 08:17:31 -0800 (PST)
> On Saturday, February 18, 2017 at 10:06:32 AM UTC-6, Tim Rentsch
> wrote:
[snip]
> Thankfully, Providence has given on line services as a
> way to rescue a few from a flood of immorality. "We few,
> we happy few."
 
Tim makes a perfectly reasonable response about fair use; and you
respond with irrelevant self-absorbed crap to parade your moral
superiority. Please stop it.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Feb 20 06:23PM

On Mon, 20 Feb 2017 07:35:53 -0800 (PST)
"Rick C. Hodgin" <rick.c.hodgin@
[snip]
> It's going to get so bad that Christians will be rounded up and put
> into prisons, and even beheaded ...
 
You are being totally over-amped, ridiculous and delusional. All you
have been asked to do is stop posting off topic postings on a newsgroup
dealing with C++, and you turn this into an issue of prison and
beheadings. The request for you to say on topic is a very modest
request which anyone who respects others would be willing to accede to.
 
Every mainstream religion has nutjobs like you and Brian. If they all
posted to this newsgroup in the fashion you do, it would be completely
unusable. Can you please try to understand this very simple point.
 
PS: please don't use the plea for sanity as another excuse for you to
post off topic crap[1] on this newsgroup.
 
[1] "Crap" is fine. Brian has blessed it for Christian use.
legalize+jeeves@mail.xmission.com (Richard): Feb 19 10:18PM

[Please do not mail me a copy of your followup]
 
David Brown <david.brown@hesbynett.no> spake the secret code
 
>I feel a lot of sympathy for folks like Christopher, and other /real/
>Christians, who have a much harder job trying to spread their message
>because of fanatics like Rick.
 
He's not a fanatic. He's an asshole, plain and simple.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 26 01:09AM +0100

On 26.02.2017 00:38, bitrex wrote:
> use it are destroyed the resource is release.
 
> Is it more appropriate to use a std::unique_ptr or a std::shared_ptr in
> the wrapper class in this circumstance?
 
`std::shared_ptr` implements shared ownership, while `std::unique_ptr`
implements single but transferable ownership.
 
So ask yourself: do I have a case of shared ownership, or do I have a
case of transferable single ownership?
 
Or do I have something else, like e.g. automatic cloning on copy?
 
 
Cheers & hth.,
 
- Alf
bitrex <bitrex@de.lete.earthlink.net>: Feb 25 07:35PM -0500

On 02/25/2017 07:09 PM, Alf P. Steinbach wrote:
 
> Or do I have something else, like e.g. automatic cloning on copy?
 
> Cheers & hth.,
 
> - Alf
 
Indeed, my point of confusion is about how boost::flyweight is operating
internally.
 
Instead of looking at the source right now (what a silly idea!) I'll
instead just randomly speculate that the flyweight type is itself
creating a wrapper type which holds a shared reference, and each time a
new class is created with a key that hashes to the same value type it
makes a new wrapper and clones the reference, rather than call the
copy/move constructor on my own.
 
So I'd guess that I'd want to use a unique_ptr for the resource in my
wrapper, as at the end of the day all flyweights that hash to an
instance of it are finally all referring to the same resource. When all
the flyweights are gone the pointer to my wrapper is released, and along
with it goes the unique_ptr contained within.
Christiano <christiano@engineer.com>: Feb 24 02:22PM -0300

On 02/23/2017 01:35 AM, Christiano wrote:
> // access d using d.day(), d.month(), and d.year()
> // make new Date to return
> }
 
I was testing some codes here.
 
See this C code:
 
/----------- a1.c -----------------\
#include <stdio.h>
 
struct house {
int a;
int b;
};
 
struct house func()
{
struct house e = {2,3};
return e;
}
 
int main()
{
int num =8;
struct house x = func();
 
printf("%d %d\n", x.a, x.b);
 
return 0;
}
\---------------------------------/
 
Now, see the second version:
 
/------------- a2.c -----------------------\
#include <stdio.h>
 
struct house {
int a;
int b;
};
 
struct house func()
{
return (struct house){2,3};
}
 
int main()
{
int num =8;
struct house x = func();
 
printf("%d %d\n", x.a, x.b);
 
return 0;
}
\--------------------------------------/
 
The "func" function in the first version locally creates a "struct
house" and then copies it to the "struct house" in the main.
 
The "func" function in the second version creates the "struct house" in
the main directly.
 
It is possible to observe this in the generated assembly code using -S
option (gcc/g++).
 
In C++ things are not different.
 
For example:
 
Date new_date_random()
{
Date x = Date{ random_day(), random_month(), random_year() };
return x;
}
 
VERSUS
 
Date new_date_random()
{
return Date{ random_day(), random_month(), random_year() };
}
 
The first version locally creates a "Date" and then copies it to the
"Date" outside. (Assuming here that there was no RVO optimization.)
 
The second version creates the "Date" outside directly.
 
That is, this information indicates that:
 
In situations where we are not receiving references from the object
outside, It is preferable whenever possible to return an unnamed literal
class object.
Jerry Stuckle <jstucklex@attglobal.net>: Feb 19 09:22AM -0500

On 2/18/2017 2:27 AM, kushal bhattacharya wrote:
> To put it in other words i want to use c++ as backend for processing tasks from the client end just as php or any other server side scripting language does
 
There isn't any library I'm aware of for either C or C++ which does what
you want.
 
The problem is you not only have to handle sending the HTML, but you
have to interpret the incoming request, handling things like parameters
and cookies. You have to build and send header strings to the client,
and those must be sent before any HTML (and indicate an error if you try
to send a header after any output). If you want to store information on
the server across requests ($_SESSION values in PHP), you must handle it
yourself.
 
Web scripting languages do a lot for you behind the scenes. Of course,
you can do it all in C or C++, but it's going to take some work.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 26 01:07AM +0100

<url: https://github.com/alf-p-steinbach/Expressive-Cpp>
 
Expressive C++ is a header only library. It implements a less unsafe,
more convenient and readable-for-non-C++-expert-folks dialect of C++. To
do this it depends on the following language extensions, which are
supported by g++, Visual C++ and CLang, and probably also by far more
compilers: • `__COUNTER__`, • `#pragma once`, • `#pragma push_macro`, •
`#pragma pop_macro`, and • use of the `$` character in identifiers.
 
The shortest possible Expressive C++ program is
 
$just{}
 
which is • shorter than a standard `main`, and • safer than a standard
`main` ¹in the case of an exception being thrown out of it, and more •
directly readable, without distracting bits such as the `int` in
 
int main(){}
 
And this is the general philosophy: ²not always shorter like here, but
safer and to the non-expert more directly readable, and generally more
convenient than the raw C++ that Expressive C++ code translates to.
 
Flavor ³example:
 
#include <p/expressive/use_weakly_all.hpp>
#include <iostream>
#include <vector> // std::vector
#include <string> // std::string
$use_weakly_all_from( std );
 
void cpp_main( ref_<const vector<string>> args )
{
for( $each arg $in enumerated( args ) )
cout << "Arg " << arg.index() << " is '" << arg.object() <<
"'.\n";
}
 
$start_with_ascii_arguments( cpp_main )
 
The `ref_` type builder, and others like it, allows one to use the
principle of substitution to construct types, as in non-C languages in
general. It also supports the practice of putting `const` first, even in
nested parts. The resulting type specifications can be naturally read in
the forward direction, unlike in raw C and C++.
 
The $ words like $each and $in above, are pseudo keywords, keywords for
the Expressive C++ dialect, implemented as macros. Expressive C++ also
offers some stuff implemented with ordinary C++ code, using C++ core
language features up to and including C++14. For example, the expression
 
$invoked{ $var x=1; while( x*x < 50 ) ++x; return x - 1; }
 
… uses an Expressive C++ pseudo keyword macro, `$invoked`, to produce a
lambda, and to pass it to some ordinary C++14 machinery that invokes
that lambda and produces its return value with the type implied by the
return statement – which e.g., as here, allows a loop in an expression.
 
Enjoy, even though this is just a version 0.3-or-something.
 
 
- Alf
 
Notes:
¹ If any statements are added, then unlike a raw `main` any exception
out of the `$just` block is caught and reported on the standard error
stream, with guaranteed stack rewinding/cleanup, and a suitable process
exit code that adheres to the OS conventions is produced.
² I've not yet found a good way to express the `:?` operator within the
limits of a macro approach.
³ Sorry about the limitation to "ascii" here. Implementing portable
Unicode command line support, which raw C++ `main` doesn't offer for
systems other than *nix, is much work, and I haven't got to that yet.
Robert Wessel <robertwessel2@yahoo.com>: Feb 24 11:41PM -0600

On Fri, 24 Feb 2017 12:50:21 -0800 (PST), 嘱 Tiib <ootiib@hot.ee>
wrote:
 
>release nor 2011.1 extended feature releases of it. It is done.
>Defects of 2011 were attempted to address in version 2014. That is
>also final. Version 2017 is under development.
 
 
Well, they do accept defect reports, and then issue corrections or
whatever to the standard as is appropriate. Here are some of the ones
for the C++11 core language:
 
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html
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.

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

Steve Keller <keller@no.invalid>: Feb 24 06:52PM +0100

For a simple interpreter I wrote a class
 
class Stmt {
public:
virtual void exec() const = 0;
...
};
 
and several statement classes derived from that. In these classes I
have a number of occurrences of code like the following:
 
class FooStmt : public Stmt {
Stmt *s;
public:
virtual void exec() const {
if (s)
s->exec();
}
};
 
Therefore, I added a wrapper
 
void exec(const Stmt *s) {
if (s)
s->exec();
}
 
However, in order to be able to call exec(const Stmt *) from inside
FooStmt, I either need to
 
a) make this wrapper a static member function of class Stmt
 
b) if the wrapper is outside of class Stmt, I have to call it using
 
::exec(s)
 
instead of only exec(s).
 
c) rename the wrapper to something different than exec.
 
It seems the compiler, when looking for an exec(const Stmt *)
function, first looks for any exec(...) function in FooStmt and if it
finds one (in this case the exec() member function without parameters)
it does not continue to look for a matching exec(const Stmt *) outside
of FooStmt. But why does is behave that way?
 
I don't like any of these solutions because a) makes the wrapper
visible in the header file and b) and c) look cumbersome.
 
Are there other suggestions?
 
Steve
"Adam C. Emerson" <azure@fox.blue>: Feb 24 08:13PM

> s->exec();
> }
> };
[snip]
 
This design looks very strange to me. Why do you both inherit from
Stmt and include a pointer to Stmt?
Cholo Lennon <chololennon@hotmail.com>: Feb 24 05:41PM -0300

On 24/02/17 17:13, Adam C. Emerson wrote:
> [snip]
 
> This design looks very strange to me. Why do you both inherit from
> Stmt and include a pointer to Stmt?
 
Because, at 1st glance, it seems like the OP is using the decorator pattern.
 
--
Cholo Lennon
Bs.As.
ARG
Steve Keller <keller@no.invalid>: Feb 25 01:10AM +0100

> [snip]
 
> This design looks very strange to me. Why do you both inherit from
> Stmt and include a pointer to Stmt?
 
Actually, there is no FooStmt but WhileStmt, IfStmt. ForStmt, etc.
which *are* statements and some contain other statements. There's
also an abstract base class Expr with a number of subclasses, and my
statements look like this
 
class WhileStmt : public Stmt {
Expr *cond;
Stmt *body;
public:
...
};
class IfStmt : public Stmt {
Expr *cond;
Stmt *s1, *s2;
public:
...
};
class ForStmt : public Stmt {
Expr *init, *cond, *iter;
Stmt *body;
public:
...
};
class ExprStmt : public Stmt {
Expr *expr;
public:
...
};
 
I think that is quite straight forward and natural.
 
Steve
Paavo Helde <myfirstname@osa.pri.ee>: Feb 25 03:25AM +0200

On 25.02.2017 2:10, Steve Keller wrote:
> doesn't match the definition of FooStmt::exec() I wouldn't count this
> as a match and continue matching in a wider scope and would find the
> actually matching global exec(const Stmt *).
 
Yes, this might seem like a good idea, but over the years I have learned
the hard way that trying to be too clever is about the worst thing a
language can do. The reason is that if the language is too clever then
the programmer is not able any more to figure out how it works and thus
it loses control over how to achieve that it wants.
 
C++ already has function overloading, Koenig lookup and other things
where it has arguably gone too clever, there is no need to make it even
more "cleverer".
 
> also, although I don't have the same problem there. What I dislike a
> little is that in s.exec() the member s doesn't really look like a
> pointer anymore.
 
You can make it look like s->exec() with some more effort, though by
some reason I suspect you are wasting your pedantry in wrong areas.
 
There are no abstract ideals to which your code should conform.
 
Instead, programming is an engineering discipline, meaning everything
serves a purpose. Consistency of the code and markup is needed only for
the maintainer programmer (including yourself 6 months ahead) to
understand the program so he can easily maintain or refactor it. In this
sense, writing some decent unit tests is probably much more helpful than
a minor stylistic consistency.
Paavo Helde <myfirstname@osa.pri.ee>: Feb 23 11:10AM +0200

On 23.02.2017 6:35, Christiano wrote:
> inside a function and then passing it through return forces the calling
> function to make a copy of an object, if that object is large it can
> make everything inefficient.
 
1) A 'date' does not look like it could be large.
 
2) Compilers have been optimizing this kind of stuff for many years
(according to Wikipedia RVO was invented in 1991).
 
3) Since C++11, we also have rvalue references and move constructors &
assignments, which work best with temporaries like function return
values (otherwise you will need to pepper the code with unwanted noise
like std::move()).
 
4) If you want to make sure that no copies are made behind the curtains
you can mark the copy constructor and assignment deleted for the class
and rely on the move ctor/assignment instead. This coincidentally means
you should make use more of function return values, not less.
 
5) As you certainly know, premature optimization is the root of all
evil. Before reducing the readability and maintainability of your code
by doing manual "optimizations" which you *believe* should make the code
faster, take some time to actually *measure* it and see if your beliefs
have any ground.
ram@zedat.fu-berlin.de (Stefan Ram): Feb 25 04:07AM

>N_TIMES( n )
 
Maybe a symbolic interpretation helps to understand this:
 
N_TIMES( m )
 
N_TIMES_AUX( MM_CONCAT( i_, __COUNTER__ ), MM_CONCAT( i_, __COUNTER__ ), m )
 
N_TIMES_AUX( MM_CONCAT_( i_, 0 ), MM_CONCAT_( i_, 1 ), m )
 
N_TIMES_AUX( MM_CONCAT__( i_, 0 ), MM_CONCAT__( i_, 1 ), m )
 
N_TIMES_AUX( i_ ## 0, i_ ## 1, m )
 
N_TIMES_AUX( i_0, i_1, m )
 
N_TIMES_AUX( i_0, i_1, m )
 
N_TIMES_AUX( i_0, i_1, m )
 
Index i_0 = 0, i_1 = m; i_0 < i_1; ++i_0
 
Now what would happen if we would remove one MM_CONCAT level?
 
#define MM_CONCAT_( a, b ) a ## b
#define MM_CONCAT( a, b ) MM_CONCAT_( a, b )
 
N_TIMES( m )
 
N_TIMES_AUX( MM_CONCAT( i_, __COUNTER__ ), MM_CONCAT( i_, __COUNTER__ ), m )
 
N_TIMES_AUX( MM_CONCAT_( i_, 0 ), MM_CONCAT_( i_, 1 ), m )
 
N_TIMES_AUX( i_ ## 0, i_ ## 1, m )
 
N_TIMES_AUX( i_0, i_1, m )
 
N_TIMES_AUX( i_0, i_1, m )
 
Index i_0 = 0, i_1 = m; i_0 < i_1; ++i_0
 
Same result!
 
Let's remove another level!
 
#define MM_CONCAT( a, b ) a ## b
 
N_TIMES( m )
 
N_TIMES_AUX( MM_CONCAT( i_, __COUNTER__ ), MM_CONCAT( i_, __COUNTER__ ), m )
 
N_TIMES_AUX( i_ ## __COUNTER__, i_ ## __COUNTER__, m )
 
N_TIMES_AUX( i___COUNTER__, i___COUNTER__, m )
 
Index i___COUNTER__ = 0, i___COUNTER__ = m; i___COUNTER__ < i___COUNTER__; ++i___COUNTER__
 
That would be too much. So you can remove one level of
MM_CONCAT, but not more, i.e., the following still works:
 
#define MM_CONCAT_( a, b ) a ## b
#define MM_CONCAT( a, b ) MM_CONCAT_( a, b )
#define N_TIMES_AUX( i, n, expr ) Index i = 0, n = expr; i < n; ++i
#define N_TIMES( n ) N_TIMES_AUX( MM_CONCAT( i_, __COUNTER__ ), MM_CONCAT( i_, __COUNTER__ ), n )
 
Disclaimer: I, too, do /not/ know the actual C++ standard
rules, I just inferred to above reduction steps from the
behavior of a specific implementation and some guesswork.
ram@zedat.fu-berlin.de (Stefan Ram): Feb 25 04:37AM

>It also occurred to me that I don't know that standard's rules that make
>this case work as unexpected, but makes the code invalid when the `if`
>is replaced with a `while` or `switch`.
 
By »invalid«, you might mean that »seven!« will /not/ be
printed in the case of a »while«. I believe that the
standard requires the »while« to behave like the »if«,
and when »seven!« is not printed, it's an error in the
C++ implementation.
 
A nested »switch«, however, clearly starts a new scope
for case-lables, so it is correct, when »seven!« is not
printed in this case.
ram@zedat.fu-berlin.de (Stefan Ram): Feb 25 05:44PM

>Still, with the compilers disagreeing it would be nice to know what the
>standard says about this.
 
Before I wrote the post that you answer to in the post
quoted above, I /did/ read the section about the switch
statement in the recent draft and tried to incorporate
what I understood from this reading into my post.
 
I assume that you are able to find "switch" in the
table of contents of the version of the standard that
you prefer to use, so that there is no need for me to
actually quote this section here.
 
>trick work. So it seems Visual C++ is right and g++ is buggy, but... :)
 
The bug seems to be in the code for /constant/ values
as conditions. IIRC, the bug disappeared yesterday when
I used a condition that is false only at runtime.
 
IIRC the JLS (Java Language Specification) might even
guarantee that »if( false )...« is removed during
compilation. Let me try this in Java:
 
Main.java
 
public final class Main
{ public static void main( final java.lang.String[] args )
{ switch( 7 )
{ case 6:
if( false )
{ case 7: java.lang.System.out.println( "is 7" ); break; }}}}
 
transcript
 
Main.java:6: error: orphaned case
{ case 7: java.lang.System.out.println( "is 7" ); break; }}}}
^
1 error
 
(same for »if( true )« and »while( true )«)
 
JavaScript:
 
{ switch( 7 )
{ case 6:
while( true )
{ case 7: console.log( "is 7" ); break; }}}
 
SyntaxError: expected expression, got keyword 'case'
 
C sharp:
 
Program.cs
 
public static class Program
{
public static void Main()
{ switch( 7 )
{ case 6:
if( false )
{ case 7: global::System.Console.WriteLine( "is 7" ); break; }}}}
 
transcript
 
Program.cs(7,9): error CS1513: } expected
ram@zedat.fu-berlin.de (Stefan Ram): Feb 25 11:09PM

>The posted article is OK, but your newsreader doesn't recognize the
>flowed format specified in the content type header:
 
Ok, thanks! Now I remember that we might have had this
discussion before. Unfortunately, in the meantime, I
forgot about the »format=flowed« content type.
 
>I believe all modern common newsreaders support flowed format, so you
>have a large number to choose from, including just using Thunderbird, as
>I do. ;-)
 
Yes, I am not using one of the modern common newsreaders.
 
Now I hope that I will be able to remember that »format=flowed«
is not displayed as intended in my newsreader.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 24 12:41AM +0100

> $var instead of auto? Why don't you like the auto keyword?
 
I don't /dislike/ `auto`. But `auto` has many different meanings, and
that makes it
 
• hard to search for e.g. variable declarations as opposed to constant
or reference declarations,
 
• hard to see at a glance what kind of declaration (such as variable or
constant, as in the array example below) a declaration is,
 
• hard to see what type a declaration is about, and
 
• I believe, difficult to learn to use correctly for a novice.
 
These are problems that are somewhat alleviated by the $ pseudo-keywords.
 
There are also problems, some mentioned below, that are irrelevant for
the use or not of pseudo-keywords, at least as long as they're macros
and not more real keywords supported by compiler extension. I think it's
easier now to do compiler extensions, with clang's support machinery.
But the last time I tried my hand at that, with gcc (for an idea about
exception handling), I found that gcc had a really complex structure
expressed in the apparently lowest possible level K&R C...
 
• • •
 
Regarding the claim of hard to see type, consider
 
auto s = "Blah";
 
Until I learned this as a special case (that didn't take long, but
until) I thought this would deduce `s` as `char const[5]`, which is
non-assignable and with length. But it deduces `s` as `char const*`.
Which is not even a constant, so one can, perhaps inadvertently, do
 
s = "Oh!";
 
Well, then perhaps change the declaration to
 
auto s[] = "Blah"; // ?
 
But contrary to what I think is a natural expectation, one just can't
use `auto` for an array item type: that won't compile.
 
The /technically/ correct way when one desires `s` as an immutable array
with length information retained, as the initializer, is to write
 
auto& s = "Blah";
 
But I wouldn't do that because it just obscures the desired result.
 
With the pseudo-keywords one can, however, write quite naturally
 
$let s = "Blah"; // `s` is const, decayed to pointer
$var s = "Blah"; // `s` is variable, decayed to pointer
$name s = "Blah"; // `s` is `char const[5]`
 
where
 
• $let → auto const, always yielding just a constant /value/;
 
• $var → auto, always yielding a mutable /variable/; and
 
• $name → auto&, always yielding just an /alias/.
 
Still lacking is a way to express
 
decay_t<decltype( *"Blah" )> s[] = "Blah";
 
which yields a mutable array, `char[5]`. A macro for this would get
/too/ ugly not just because it would have to take the initializer as
argument, but because that initializer could easily contain a comma or
two, which would be interpreted as macro argument separators. Well, a
variadic macro would be able to handle that, but it would still be ugly.
 
• • •
 
As an example of a problem that as far as I can see is not generally
solvable with keywords, consider the following code:
 
template< class Some_type >
using ref_ = Some_type&;
 
template< class Stream >
auto int_from( ref_<Stream> stream )
-> int
{
int result;
stream >> result;
if( stream.fail() ) { abort(); }
return result;
}
 
auto input_int( ref_<const wstring> prompt )
-> int
{
wcout << prompt;
return int_from( wcin ); // <--- Deducing the type Stream.
}
 
That works fine.
 
But the second declaration here does not work fine:
 
void foo()
{
auto& yep = wcin;
ref_<auto> nope = wcin; // <--- Uh oh.
 
(void) yep; (void) nope;
}
 
The problem here isn't the reference, which is just one specific use
case, it's the use of `auto` as a template (alias) argument.
 
The good old general template argument type deduction can see right
through that little template alias, as in the `ref_<Stream>`, but `auto`
just doesn't cut it.
 
 
> Why do you prefer obfuscation to idiomatic C++? What you are doing
> try to make C++ code look like code from other inferior languages is
> really egregious.
 
Well, those are emotional reactions.
 
I don't share them. :)
 
Actually I felt happy being able to express how I think about things
(just also slightly annoyed at having to use evil macros etc.).
 
For re the inferior languages, I think that to use C++ in a good way one
must have a clear picture of what /hypothetical language constructs/,
usually very much like constructs from other languages that one has
used, one is trying to implement with one's C++ code.
 
For example, to me, header and implementation files, and the whole thing
with include guards etc., implements modules, like Modula-2 MODULE or
Pascal UNIT or Ada PACKAGE. I haven't really used Ada but I've read some
books about it. And for example, to me, my `i_up_to` for a range-based
loop, implements in an imperfect but practically useful way, Python 2.7
`xrange` or Python 3.x `range`. And correspondingly, e.g. the $let
pseudo keyword in the expressive dialect implements in a very restricted
and awkward, but IMHO still very practically useful, way, a logical
`let` from a functional language or maths.
 
 
Cheers!,
 
- Alf
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 25 10:16PM

On 23/02/2017 17:57, Mr Flibble wrote:
 
> All this $let_mutable and such bollocks makes your code harder to grok
> than standard C++ so I have no interest in examining it and therefore
> answering your questions about it.
 
Also use of dollar sign ($) in identifiers is implementation defined and
thus non-portable and to be avoided.
 
/Flibble
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 22 12:06AM

On 21/02/2017 23:58, Rick C. Hodgin wrote:
[snip]
 
> are to teach those who have an ear to hear the truth about their
> sin, of condemnation for sin, and their need of forgiveness by
> Jesus Christ.
 
Jesus Christ never existed; he was a fictional invention of the latter
half of the first century when the gospels were being written.
 
[snip]
 
/Flibble
Real Troll <real.troll@trolls.com>: Feb 21 06:36PM -0400

Can we just kill this thread now as it has reached its shelf life.
 
Please kill-file that one person who keeps posting non C++ stuff and the
problem is solved once and for all.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 21 07:10PM

On 21/02/2017 15:21, Rick C. Hodgin wrote:
 
> It's a very common practice and ploy by the enemy to get people to come
> to summary conclusions on things based on partial evidence. It's very
> easy (and natural in our flesh) to mock those things we do not understand.
 
It is you that lacks understanding; the understanding that the god you
follow doesn't exist. I am not sure if this lack of understanding is
just deliberately obtuse fucktardary or you are genuinely that stupid.
 
You are entitled to your beliefs just as we are entitled to ours; stop
trying to trample over OUR beliefs: this is not the correct forum for
proselytizing.
 
/Flibble
red floyd <no.spam@its.invalid>: Feb 25 09:37AM -0800

> address from god knows where.
> What is dl_main? Is it when the loader finally jumps to the start
> of the main program?
 
This is not a C++ language question. Please ask in a Linux forum
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 25 11:36PM +0100

On 25.02.2017 19:10, Stefan Ram wrote:
 
> o use a Newsreader that will not break long lines or
 
> o to limit the line length so that the lines are not
> wrapped by the Newsreader.
 
The posted article is OK, but your newsreader doesn't recognize the
flowed format specified in the content type header:
 
Content-Type: text/plain; charset=utf-8; format=flowed
 
I.e. you're using a somewhat deficient newsreader.
 
Flowed format was specified in an RFC called "son of"-something.
Essentially it uses a space at the end of each line as a /line
continuation character/, like `\` in C and C++, or `_` in VBScript, or
`^` in the Windows command interpreter. I don't recall how it deals with
a line that originally has a space at the end.
 
Due to the comments in your headers I suspect that the newsreader is a
home-grown one. Please note that no archivers, in particular Google
Groups (formerly Deja news), will read and respect this comment:
 
X-No-Archive-Readme: "X-No-Archive" is only set, because this
prevents some services to mirror the article via the web (HTTP). But
Stefan Ram hereby allows to keep this article within a Usenet archive
server with only NNTP access without any time limitation.
 
Also note that X-No-Archive doesn't prevent servers from archiving
responses that quote all you wrote, and some people tend to quote
everything in what they respond to.
 
• • •
 
I believe all modern common newsreaders support flowed format, so you
have a large number to choose from, including just using Thunderbird, as
I do. ;-)
 
 
Cheers!,
 
- Alf
Ben Bacarisse <ben.usenet@bsb.me.uk>: Feb 25 03:13PM


> I'm not sure, but I think BCPL, which C was based on, supported
> control structures within expressions; at least had curly braces in
> expressions?
 
It has expressions of the form VALOF <block> used like this:
 
LET l = VALOF $(
LET n, x = 0, 1
WHILE x < y DO n, x = n+1, f(x)
RESULTIS n
$)
 
In fact, that's how functions that need a block are defined.
 
> Anyway, after C++11 and C++14 we can now do that in C++:
 
Surely an example in pure C++ would have been better? The above in C++
is:
 
int p = [&]{
int n = 0, x = 1;
while (x < y) n++, x=f(x);
return n;
}();
 
There has to be a y and and f in scope in both examples.
 
In cases like this you don't need to capture anything in the lambda --
you can just pass arguments:
 
int l = [](int y, int (*f)(int)) {
int n = 0, x = 1;
while (x < y) n++, x=f(x);
return n;
}(123456789, [](int x){ return x*10; });
 
 
> {
> $let sum = $invoked{ int s{}; for( int i = 1; i <= 8; ++i ) s +=
> i; return s; };
 
I'm guessing this is the thunk being called and that it means:
 
auto sum = [&]{
int s{}; for( int i = 1; i <= 8; ++i ) s += i; return s;
}();
 
> and invokes the specified lambda, producing an expression return value
> via C++14 automatic return type deduction, and that works with MSVC
> 2015. :)
 
Where is the % operator being used? Is that masked by the $xyz stuff or
is it in the header?
 
--
Ben.
Paavo Helde <myfirstname@osa.pri.ee>: Feb 25 10:49AM +0200

On 25.02.2017 9:24, Shiyao Ma wrote:
 
> If so, what part?
 
> http://eel.is/c++draft/temp.spec doesn't seem to force the compiler to generate the code.
 
> I'd afraid this might result a link error.
 
Explicit specialization and explicit instantiation are different things.
Only the latter forces instantiation (aka "code generation" in your terms).
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 25 12:30AM +0100

On 25.02.2017 00:24, Paul wrote:
 
> I noticed this: https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms
 
> However, it seems to be exhaustive, without stressing the more common
> and standard patterns.
 
I haven't clicked it but "More" seems to imply a separate original list.
 
Cheers & hth.,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 25 12:28AM +0100

On 24.02.2017 23:59, Öö Tiib wrote:
> Most programs written nowadays are multi-threaded and so CoW
> is not too good idea most of the time.
 
Uhm, thread safety is an orthogonal issue. Adding illusory thread safety
to a string class is going to cost, no matter the internal implementation.
 
I write "illusory" because if one shares a mutable string object between
threads, it would be impractical to lock down the object any time its
`operator[]` returns a reference that possibly could be stored by the
thread and used to modify the string at arbitrary times.
 
The standard library's approach of most classes being thread-agnostic is
fine, I think. It's the responsibility of the code that uses those
classes, to ensure thread safe operation. E.g. by simply not sharing
mutable objects between threads.
 
 
Cheers!,
 
- Alf (opinionated, for the occasion)
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 25 03:22AM +0100

My original N_TIMES macro, called $n_times, used a range based `for`
loop. But g++ warned about the loop control variable being unused, and I
found no way to shut it up in code (only way was to turn off that
warning in the g++ invocation). So I'm thinking of using this scheme:
 
 
#include <iostream>
#include <stddef.h>
using namespace std;
 
using Size = ptrdiff_t;
using Index = Size;
 
#define MM_CONCAT__( a, b ) a ## b
#define MM_CONCAT_( a, b ) MM_CONCAT__( a, b )
#define MM_CONCAT( a, b ) MM_CONCAT_( a, b )
 
#define N_TIMES_AUX( i, n, expr ) Index i = 0, n = expr; i < n; ++i
#define N_TIMES( n ) N_TIMES_AUX( MM_CONCAT( i_, __COUNTER__ ),
MM_CONCAT( i_, __COUNTER__ ), n )
 
auto main() -> int
{
int const n = 7;
for( N_TIMES( n ) )
{
cout << "! ";
}
cout << endl;
}
 
 
Here __COUNTER__ is a language extension supported by Visual C++, g++
and clang, and probably far more compilers. Along with the other
language extensions I use (#pragma once, #pragma push, #pragma pop, $ in
identifiers) it's widely supported but not standard, while all sorts of
never-seen-in-the-wild things are being standardized. Hrmf. Innovating
committee. I aim just for the supporting compilers.
 
Anyway, even though I just wrote this code, and e.g. applied the
concatenation trick out of some acquired instinct for that, I don't
understand the details of how it avoids the actual macro argument `n`,
given in `main`, being replaced with the value of the formal macro
argument `n` i N_TIMES_AUX. It works but I don't know how...
 
So, my attempt at breaking it failed, which I'm happy about. Also, that
I identified a big hole in my understanding, that I could ask about. But
is there still some way to break this code?
 
 
Cheers!
 
- Alf
Ian Collins <ian-news@hotmail.com>: Feb 25 10:48AM +1300

On 02/25/17 09:49 AM, Paul wrote:
> Here is some basic pimpl code below:
> I don't understand why this is legal. It seems that class widget{..}
> defines widget as a base class.
 
Where?
 
> And then class widget is then redefined as a class privately inheriting
> from impl.
 
Where?
 
> Why isn't widget being illegally defined twice?
> Also, can someone explain pimpl to me or direct me to a good explanation?
 
I think you need to explain where your conclusions (above) came from,
the code does not support them.
 
> class widget {
 
No base class...
 
> private:
> class impl;
> unique_ptr<impl> pimpl;
 
Contains a nested impl class, no inheritance.
 
--
Ian
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 25 01:59PM +0100

Macro-Magic (MM) is a header-only library with a macro MM_APPLY to
invoke a specified macro on each of up to 21 arguments. There's also
MM_APPLY_WITH_FIXED_ARG to pass a specified fixed first argument to the
invoked macro, and there's MM_NARGS to count the number of arguments
passed to a variadic macro. And MM_CAT to concatenate with expansion.
 
GitHub repository:
<url: https://github.com/alf-p-steinbach/Macro-Magic/>
 
This is pretty old code, from at least back in 2013 or perhaps years
earlier than that, based on an original __VA_NARG__ macro by Laurent
Deniau that he posted on 17 January 2006 to [comp.std.c].
 
<url:
https://groups.google.com/forum/?fromgroups=#!topic/comp.std.c/d-6Mj5Lko_s>
 
I've modified it to work with Visual C++.
 
I see now that I posted it on GitHub that I forgot to add a license, but
it's Boost license 1.0.
 
 
Cheers, & enjoy!,
 
- Alf (hoping there are not too many bugs: code like this touches on an
area where compilers are generally not standard-conforming!)
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 26 03:29AM

On 26/02/2017 00:07, Alf P. Steinbach wrote:
> ³ Sorry about the limitation to "ascii" here. Implementing portable
> Unicode command line support, which raw C++ `main` doesn't offer for
> systems other than *nix, is much work, and I haven't got to that yet.
 
Use of dollar sign ($) in identifiers is implementation defined as to
whether it works so is unportable and should be avoided.
 
/Flibble
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.