Saturday, February 25, 2017

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

thebtc@hotmail.com: Feb 25 11:44AM -0800

Ok I considered what you both said and changed some things around.
 
#include <iostream>
#include <fstream>
#include <string>
#include "lapacke.h"
 
using namespace std;
 
int main(){
// list the declarations
int matrix_layout = LAPACK_COL_MAJOR; // store arrays in column major
char jobz = 'N'; // computes eigenvalues only
char uplo = 'U'; // stores the upper triangle of a in an array a
lapack_int n = 10; // the order of the matrix a
float* a[10][10] = {
{1, 11, 7, 9, 7, 11, 7, 9, 2, 11},
{11, 4, 10, 10, 6, 2, 9, 6, 10, 0},
{7, 10, 3, 5, 4, 4, 4, 4, 6, 10,},
{9, 10, 5, 3, 8, 8, 3, 5, 1, 8,},
{7, 6, 4, 8, 8, 10, 5, 6, 10, 0},
{11, 2, 4, 8, 10, 9, 4, 3, 5, 11},
{7, 9, 4, 3, 5, 4, 3, 10, 7, 2},
{9, 6, 4, 5, 6, 3, 10, 11, 1, 7},
{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
lapack_int lda = 10; // the leading dimension of the array a
float* w[10]; // stores the eigenvalues
 
// print the eigenvalues
ofstream fout("eigenvaluesA.txt"); // title of text output
lapack_int LAPACKE_ssyev(int matrix_layout, char jobz, char uplo,
lapack_int n, float* a, lapack_int lda, float* w); // compute the eigenvalues
int i;
for (i = 0; i < n; i++);
fout << w[i] << endl; // record the eigenvalues
fout.close();
 
return 0;
};

 
I realized that I wasn't actually printing my eigenvalues. I was printing...a statement. The error I get now is "error: invalid conversion from 'int' to 'float*' [-fpermissive]" which I haven't been able to fix. Is that because float shouldn't be a pointer?
thebtc@hotmail.com: Feb 25 11:49AM -0800

You were both right. I went back and made a lot of changes. Here is the updated code:
 
#include <iostream>
#include <fstream>
#include <string>
#include "lapacke.h"
 
using namespace std;
 
int main(){
// list the declarations
int matrix_layout = LAPACK_COL_MAJOR; // store arrays in column major
char jobz = 'N'; // computes eigenvalues only
char uplo = 'U'; // stores the upper triangle of a in an array a
lapack_int n = 10; // the order of the matrix a
float a[10][10] = {
{1, 11, 7, 9, 7, 11, 7, 9, 2, 11},
{11, 4, 10, 10, 6, 2, 9, 6, 10, 0},
{7, 10, 3, 5, 4, 4, 4, 4, 6, 10,},
{9, 10, 5, 3, 8, 8, 3, 5, 1, 8,},
{7, 6, 4, 8, 8, 10, 5, 6, 10, 0},
{11, 2, 4, 8, 10, 9, 4, 3, 5, 11},
{7, 9, 4, 3, 5, 4, 3, 10, 7, 2},
{9, 6, 4, 5, 6, 3, 10, 11, 1, 7},
{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
lapack_int lda = 10; // the leading dimension of the array a
float w[10]; // stores the eigenvalues
 
// print the eigenvalues
ofstream fout("eigenvaluesA.txt"); // title of text output
lapack_int LAPACKE_ssyev(int matrix_layout, char jobz, char uplo,
lapack_int n, float* a, lapack_int lda, float* w); // compute the eigenvalues
int i;
for (i = 0; i < n; i++);
fout << w[i] << endl; // record the eigenvalues
fout.close();
 
return 0;
};
 
I included the LAPACKE_ssyev part in the main, and I also fixed the printing part since I realized I wasn't actually printing my eigenvalues, I was printing some junk. I'm not getting any compiler errors now but my text file gives me the number "6.61179e+24" and nothing else. I'm not sure why that's happening.
Christian Gollwitzer <auriocus@gmx.de>: Feb 25 09:24PM +0100


> lapack_int LAPACKE_ssyev(int matrix_layout, char jobz, char uplo,
> lapack_int n, float* a, lapack_int lda, float* w); // compute the eigenvalues
 
This does not compute anything, instead it declares the function
LAPACKE_ssyev (i.e. tells the compiler that the function exists). Leave
out all the types and it should at least be closer to what you need.
 
 
> eigenvalues, I was printing some junk. I'm not getting any compiler
> errors now but my text file gives me the number "6.61179e+24" and
> nothing else.
 
 
Not surprising - since you never actually called the Lapack function you
are printing uninitialized memory as float, which usually gives lots of
junk numbers or zero values.
 
Christiah
Ben Bacarisse <ben.usenet@bsb.me.uk>: Feb 25 08:36PM


> Ok I considered what you both said and changed some things around.
 
You've fixed a couple of things and broken a couple of things that were
right before. In general, you can't write a program by trying things
out to see what happens!
 
The trouble is I don't know how much you want to learn about programming
or C++ or even if this is come course exercise. I'm going to point out
some things about your code and then show you a working example. If you
don't want to see a working example, just don't scroll down at the end
of this post.
 
> #include <iostream>
> #include <fstream>
> #include <string>
 
You don't need <string>
 
> char jobz = 'N'; // computes eigenvalues only
> char uplo = 'U'; // stores the upper triangle of a in an array a
> lapack_int n = 10; // the order of the matrix a
 
If you make this const you would be able to use it in the two array
declarations. It's generally better not to keep repeating numbers like
10, but to give them a name and use that instead.
 
> {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
 
This is the source of the error you report below. You have declared the
array a to be of pointers and you have then tried to put 100 number into
it. Remove the *.
 
> lapack_int lda = 10; // the leading dimension of the array a
> float* w[10]; // stores the eigenvalues
 
Remove the *. You want and array of floats.
 
> ofstream fout("eigenvaluesA.txt"); // title of text output
> lapack_int LAPACKE_ssyev(int matrix_layout, char jobz, char uplo,
> lapack_int n, float* a, lapack_int lda, float* w); // compute the eigenvalues
 
This is not a function call. The call does not have the types, but
instead lists the values to be passed. And (as you will see if you look
at my example) you don't have to name every single one of them.
 
> printing...a statement. The error I get now is "error: invalid
> conversion from 'int' to 'float*' [-fpermissive]" which I haven't been
> able to fix. Is that because float shouldn't be a pointer?
 
Spoiler alert: here is a working version (after the dots).
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
#include <iostream>
#include "lapacke.h"
 
int main(){
const lapack_int n = 10;
float a[n][n]= {
{1, 11, 7, 9, 7,11, 7, 9, 2,11},
{11, 4,10,10, 6, 2, 9, 6,10, 0},
{7, 10, 3, 5, 4, 4, 4, 4, 6,10},
{9, 10, 5, 3, 8, 8, 3, 5, 1, 8},
{7, 6, 4, 8, 8,10, 5, 6,10, 0},
{11, 2, 4, 8,10, 9, 4, 3, 5,11},
{7, 9, 4, 3, 5, 4, 3,10, 7, 2},
{9, 6, 4, 5, 6, 3,10,11, 1, 7},
{2, 10, 6, 1,10, 5, 7, 1,10, 5},
{11, 0,10, 8, 0,11, 2, 7, 5, 1}
};
float w[n];
 
if (LAPACKE_ssyev(LAPACK_COL_MAJOR, 'N', 'U', n, a[0], n, w) == 0) {
for (int i = 0; i < n; i++)
std::cout << w[i] << " ";
std::cout << "\n";
}
}
 
 
--
Ben.
thebtc@hotmail.com: Feb 25 12:36PM -0800

> This does not compute anything, instead it declares the function
> LAPACKE_ssyev (i.e. tells the compiler that the function exists). Leave
> out all the types and it should at least be closer to what you need.
 
I've already tried that before though and I kept getting errors. I end up getting "expression list treated as compound expression in initializer [-fpermissive]" and "invalid conversion from 'float*' to 'int' [-fpermissive]".
 
> Not surprising - since you never actually called the Lapack function you
> are printing uninitialized memory as float, which usually gives lots of
> junk numbers or zero values.
 
I'm not sure how I'm supposed to call it? I'm following someone's blog (except they are solving a system of linear equations, not calculating eigenvalues) and after they write the lapacke part they have a loop and that's it.
thebtc@hotmail.com: Feb 25 01:01PM -0800

> You've fixed a couple of things and broken a couple of things that were
> right before. In general, you can't write a program by trying things
> out to see what happens!
 
Sorry, I realized I misinterpreted the first post you wrote.
 
> some things about your code and then show you a working example. If you
> don't want to see a working example, just don't scroll down at the end
> of this post.
 
I want to learn how to use c++ properly and to understand why I am doing the things I'm doing. Yes, this is for a course assignment, sorry if that makes it not allowed to post. I had been working on this assignment for 2 days and I have a week to do it. The course lecture notes I have found very unhelpful for my learning because they are mostly just copy paste of someone's uncommented code. I have been using the web to learn about lapack and how to use it but not everything out there answers my questions.
 
> Remove the *. You want and array of floats.
 
I realized the issue with the pointers yes, so I had fixed them. But thanks for the confirmation!

I just want to explain a little my layout of my code. I realize that to a c++ expert it looks clunky. But I have had marks taken off for insufficient comments so that's why I defined everything explicitly rather than passing them to the lapacke function as you did- because it gives me an opportunity to add extra comments and define everything in an obvious way to prevent marks from being removed.
 
So supposing if I wanted to define everything at the top explicitly, I would need to then include types and variable names in the lapacke function, is that correct? Because I noticed that when I did that, I didn't get an error. Also could you please explain why the lapacke function in your example ==0?
 
Thank you for your help!
Christian Gollwitzer <auriocus@gmx.de>: Feb 25 10:14PM +0100

> rather than passing them to the lapacke function as you did- because
> it gives me an opportunity to add extra comments and define
> everything in an obvious way to prevent marks from being removed.
 
That is generally good advice. Especially with the obscure LAPACK
functions - they come from old FORTRAN code, which is very different
from C - it is hard to understand what the parameters are supposed to
do. Naming and commenting them makes it much easier, stick with that.
 
> Also could you please explain why the lapacke
> function in your example ==0?
 
The lapack function returns 0 if it was successful, so this tests if the
functino could compute the eigenvalues. Possible reasons for failure are
listed in the documentation; for example if you set the jobz to 'A'
(only 'N' or 'V' are allowed), then it does not compute anything and
returns -1.
 
If you are just learning, I want to point out some more subtlety from
Ben's solution. You have "float a[10][10]" and LAPACK expects a pointer
to the first element in this array "float *a". Ben passes
 
a[0]
 
which is correct, but obscure for a non-guru. Instead, you can write
 
&(a[0][0])
 
which means take the address of the element at 0,0 (the first element).
 
Christian
thebtc@hotmail.com: Feb 25 02:22PM -0800

Thanks so much for the explanations Christian, that cleared some things up!
 
I seem to be stuck again with an error. Here is my updated code:
 
 
#include <iostream>
#include <fstream>
#include "lapacke.h"
 
using namespace std;
 
// allocate space for function LAPACKE_ssyev
extern lapack_int LAPACKE_ssyev(int* matrix_layout, char* jobz, char* uplo, const lapack_int* n,
float* a, const lapack_int* lda, float* w);
 
int main(){
// list the declarations
int matrix_layout = LAPACK_COL_MAJOR; // store arrays in column major
char jobz = 'N'; // computes eigenvalues only
char uplo = 'U'; // stores the upper triangle of a in an array a
const lapack_int n = 10; // the order of the matrix a
float a[n][n] = {
{1, 11, 7, 9, 7, 11, 7, 9, 2, 11},
{11, 4, 10, 10, 6, 2, 9, 6, 10, 0},
{7, 10, 3, 5, 4, 4, 4, 4, 6, 10,},
{9, 10, 5, 3, 8, 8, 3, 5, 1, 8,},
{7, 6, 4, 8, 8, 10, 5, 6, 10, 0},
{11, 2, 4, 8, 10, 9, 4, 3, 5, 11},
{7, 9, 4, 3, 5, 4, 3, 10, 7, 2},
{9, 6, 4, 5, 6, 3, 10, 11, 1, 7},
{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
const lapack_int lda = n; // the leading dimension of the array a
float w[n]; // stores the eigenvalues
 
// open output file
ofstream fout("eigenvaluesA.txt");
 
// compute the eigenvalues; function returns 0 if successful
if (LAPACKE_ssyev(matrix_layout, jobz, uplo, n, &(a[0][0]), lda, w) == 0){
int i;
for (i = 0; i < n; i++);
// print the eigenvalues
fout << w[i] << endl;
};
// close file
fout.close();
 
return 0;
};
 
 
I keep getting the error
"/tmp/ccA0hQz3.o: In function `main':
eigen.cc:(.text+0x97): undefined reference to `LAPACKE_ssyev'
collect2: error: ld returned 1 exit status"
I looked up what that meant and mostly people are saying its because the function name is not spelled right. But mine is. So then I thought that maybe the compiler doesn't understand what this function is because I haven't allocated space to it beforehand. So I did that at the top, before my main function, but that doesn't seem to help. Some people who have had this problem have solved it by writing extern "C"{ extern function name and inputs}; but I tried that and it didn't work either.
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
Ben Bacarisse <ben.usenet@bsb.me.uk>: Feb 25 11:10PM

thebtc@hotmail.com writes:
<snip>
 
> rather than passing them to the lapacke function as you did- because
> it gives me an opportunity to add extra comments and define everything
> in an obvious way to prevent marks from being removed.
 
Obviously do what you must to get the marks, but I'd like to offer an
alternative to the answer you've already had about this. I don't object
to comments, but I don't think that adding names like 'jobz' and 'uplo'
really helps much at all.
 
And as for the first argument, the named constant is arguably more
helpful in the call than in a variable:
 
LAPACKE_ssyev(LAPACK_COL_MAJOR, // hardly needs much comment
 
whereas
 
LAPACKE_ssyev(matrix_layout, // OK, but *what* layout is being used?
 
So, by all means document what you are doing. There is no need to avoid
comments just because you don't use extra variables and, when you do,
you can choose more expressive names than the ones chosen for the
function's prototype:
 
float eigenvalues[n];
LAPACKE_ssyev(LAPACK_COL_MAJOR,
'N', // compute only the eigenvalues
'U', // store only the upper triangle
n, // the dimension of the square input array
a[0], // the symmetric nxn input array, passed as a
// pointer to the first element (a[0] == &a[0][0])
n, // the leading dimension of the array
eigenvalues // where to store the computed results, passed as
// a pointer to the first element.
);
 
(My comments may not be good ones -- I don't know the library well.)
 
> So supposing if I wanted to define everything at the top explicitly, I
> would need to then include types and variable names in the lapacke
> function, is that correct?
 
I think you asking about the
 
lapack_int LAPACKE_ssyev(int matrix_layout, char jobz, char uplo,
lapack_int n, float* a, lapack_int lda, float* w);
 
part that you included. That's a function prototype and it is needed,
but it's already in the "include file" you reference at the start:
 
#include "lapacke.h"
 
which will also define all the special types like lapack_int and so on.
 
> Because I noticed that when I did that, I
> didn't get an error.
 
But this then makes me unsure that I understood your question about
types are names.
 
> Also could you please explain why the lapacke
> function in your example ==0?
 
All of these functions indicate success by returning 0. You should
always check this sort of return value as printing anything from the w
array will be meaningless if LAPACKE_ssyev did not return 0.
 
--
Ben.
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 05:56PM

>#define MM_CONCAT_( a, b ) a ## b
>#define MM_CONCAT( a, b ) MM_CONCAT_( a, b )
 
I can now explain this a little bit more:
 
Usually, the parameters /are/ expanded in macro expansion,
so that when
 
#define id(x) x
 
is applied as
 
id(__COUNTER__)
 
it becomes 0. This expansion goes to an unlimited depth,
so that after
 
#define a __COUNTER__
 
id(a)
 
also will become 0.
 
There only is a special rule for »#« and »##« which will
suppress the expansion of the parameters when they are
used as operands of »#« or »##« (for C: n1570 6.10.3.1).
 
Thus, after
 
#define s(x) #x
 
s(__COUNTER__)
 
becomes
 
"__COUNTER__"
 
. Therefore, we just need a single level with a "normal"
macro where the parameter is not an operand of a hash
sign operator to stringify the expansion of __COUNTER__
instead. Viz,
 
id(__COUNTER__)
 
is
 
0
 
and after
 
#define g(x) s(x)
 
,
 
g(__COUNTER__)
 
first becomes
 
s(0)
 
and then
 
"0"
 
.
ram@zedat.fu-berlin.de (Stefan Ram): Feb 25 06:10PM

>// $e::impl::Gurkemeie{} % []( decltype( instantiation ) =
>instantiation )
 
As once before, I recommend to either
 
o use traditional comments or
 
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.
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
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.
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.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 25 05:36PM +0100

On 25.02.2017 16:13, Ben Bacarisse wrote:
> RESULTIS n
> $)
 
> In fact, that's how functions that need a block are defined.
 
Thanks! I was pretty sure it was supported, but I had some doubt
lingering. I never used the language.
 
 
[snip]
>> 2015. :)
 
> Where is the % operator being used? Is that masked by the $xyz stuff or
> is it in the header?
 
The `$defined` macro. I put the definition in a comment at top, but:
 
#define $invoked $e::impl::Gurkemeie{} % []()
 
Where `Gurkemeie` is an empty class defined in that namespace: its only
purpose is to guide Argument Dependent Lookup to find that `operator%`.
 
And now with your example to open my eyes, I see that this is just wrong
as a general definition. There should be a capture by reference. Thanks
again!
 
There is/will be a standard library invocation function in C++17,
¹`std::invoke`, and with C++11 the ²`std::reference_wrapper::operator()`
can invoke things. But these invokers put the invocation act, and any
arguments, textually after the lambda body. I feel that that's awkward,
that the most important information isn't up front, but later at the end.
 
Anyway, the starting point was `$invoked_with`, to define a way to add
RAII-like init and cleanup to a block of code, e.g. for automatic mutex
or a library envelope, without having to invent unnatural & unused names
for these objects. I implemented that first as a range based `for`, but
g++ complained with a warning about unused but assigned variable, even
when I made its constructor do things. Then I implemented it as a
conventional `for` loop, that iterated exactly once. But, during a visit
to a certain small room it occurred to me that if I did it with a lambda
with defaulted argument, then that same mechanism could be reused for
control structures in expressions, as with `$invoked`. I failed to see
that it would need a semicolon at the end, but I still think it's
better; just a single general mechanism.
 
Cheers!,
 
- Alf
 
Links:
¹ <url: http://en.cppreference.com/w/cpp/utility/functional/invoke>
² <url:
http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/operator()>
"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
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 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
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
Paavo Helde <myfirstname@osa.pri.ee>: Feb 25 05:16PM +0200

On 25.02.2017 14:46, Shiyao Ma wrote:
> My question has nothing to do with `explicit instantiation'
 
> I was saying `explicit specialization', not `explicit instantiation'.
 
OK, I see.
 
A full specialization of a template is technically very similar to an
ordinary non-template definition, so I guess in practice it might indeed
have the same effect as an explicit instantiation. However, from reading
the standard I get the feeling this is not guaranteed.
 
I think the most relevant point is 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."
 
Note that this "explicit specialization" is not mentioned here. I
believe that if it was meant to have the same effect, it would have been
included here.
 
So my take at the moment is that in order to be standard-compliant one
needs to also add explicit instantiation after the explicit
specialization when the latter is not visible in all relevant TU-s; if
it accidentally works without explicit specialization then it is thanks
to the "no diagnostic required" loophole above.
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 ... ;-)
"Öö Tiib" <ootiib@hot.ee>: Feb 25 06:56AM -0800

On Saturday, 25 February 2017 07:44:23 UTC+2, Alf P. Steinbach wrote:
> standard says about this. I guess C++ /should/ behave like old C here
> for backward compatibility, e.g. in order to make the old Duff's device
> trick work. So it seems Visual C++ is right and g++ is buggy, but... :)
 
Yes, gcc seems to not work also with 'for(;0;)'.
 
Perhaps they have screwed up there something when they implemented
'__builtin_fallthrough' or some other thing like that.
"Öö Tiib" <ootiib@hot.ee>: Feb 25 06:38AM -0800

On Saturday, 25 February 2017 02:40:16 UTC+2, Alf P. Steinbach wrote:
 
> const Cow_string sb = ...
 
> initialized as a copy of tread A's
 
> Cow_string sa = ...
 
About like that. That sb is most likely non-const member of some
object (task input data) and may be later copied by B into some other
non-const string but in essence that was what I meant. Both sa and sb
are first owned by A then ownership of sb is transferred to b. CoW
however keeps that shared ownership alive behind scenes.
 
> 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.
 
Yes and all what I'm saying that there is additional internal synchronized
check of reference counts in every write access just for case because
figuring out what two strings may have shared content is non-trivial
from outside. That makes a string slow compared to string that does not
do that but instead has small string optimization (up to 22 byte
strings have one level of indirection less).
 
> 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.
 
How recently you have profiled that? The lock-free atomic thingies seem
more expensive than good old mutexes in multiprocessor systems in my tests.
 
There is a surface somewhere in space of high frequency of copies and
rare writes into large sized objects from where CoW starts to win.
However making lot of copies of large objects can be likely reduced by
other means instead of making the copy lazy.
 
> 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".
 
You are correct that the synchronized access of reference counts at low
level does not make the class thread safe. It still is mandatory for
CoW even if we have external locks outside.
I do not understand what scenario you meant with leaking details.
If something is thread-safe then that is not implementation detail but
important feature.
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: