- Lapacke inputs - 10 Updates
- Silly undead code. - 5 Updates
- Back to BCPL: using lambdas to do e.g. loops within expressions - 3 Updates
- A baffling bug in my bignumber code (expressive C++ dialect) - 1 Update
- Is this N_TIMES loop macro safe for all arguments? - 1 Update
- aborts at dl_main (in /lib64/ld-2.22.so) - 1 Update
- does the language guarantee `explicit specialization' will generate the code ? - 2 Updates
- Silly undead code. - 1 Update
- copy-on-write - 1 Update
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:
Post a Comment