- A baffling bug in my bignumber code (expressive C++ dialect) - 3 Updates
- copy-on-write - 2 Updates
- Is this N_TIMES loop macro safe for all arguments? - 1 Update
- A baffling bug in my bignumber code (expressive C++ dialect) - 5 Updates
- Overloading global function in a class - 2 Updates
- does the language guarantee `explicit specialization' will generate the code ? - 1 Update
- Lapacke inputs - 2 Updates
- Header-only C++, what is the point? In C this would be a obvious mistake - 1 Update
- Plan to go to church Sunday - 2 Updates
- boost::flyweight and smart pointers - 2 Updates
- Returning class object: is it inefficient? - 1 Update
- best c++ library in order to integrate c++ with web application - 1 Update
- Announce: Expressive C++, a readability/safety/convenience dialect of C++. - 1 Update
- "Distinguishing between maybe-null vs never-null is the important thing" - 1 Update
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. |
No comments:
Post a Comment