- "Jonathan Blow: "C++ is a weird mess"" - 9 Updates
- Some C++14 code - 5 Updates
- How exceptions are implemented? - 3 Updates
- Namespace indentation - 1 Update
- Some C++14 code - 1 Update
- Toggling "Touch Keyboard" On/Off, Firefox and Chrome. - 1 Update
- Fizz Buzz - 1 Update
- Destructor elision - 1 Update
- Like, who's sabotaging who, or is buggy, wrt. locales? - 1 Update
- High horse - 1 Update
- integer conversion operator conditional on size of integer - 1 Update
Lynn McGuire <lynnmcguire5@gmail.com>: Jul 17 02:36PM -0500 On 7/17/2018 12:47 PM, Richard wrote: > ...but back to the topic of the article. This is like the 40th time > that someone has complained about C++ and introduced a new language to > "solve" the problems that C++ has. Shoot, it could the 400th time. Lynn |
Thiago Adams <thiago.adams@gmail.com>: Jul 23 07:41AM -0700 On Friday, July 20, 2018 at 5:51:57 PM UTC-3, Richard wrote: ... > However, I find myself working in larger problem spaces now and C > doesn't scale well to larger code bases because of its limited ability > to express abstractions directly in code. I would like to understand better what you want to say. More abstract code scale better? How? Maybe because you can do the same think in less lines of code? I believe C can scale well. (Maybe SOs are a good sample?) One case where C would not scale well is let's say you build a container (like map something like that) and then you have to duplicate the code and create other containers because you don't have templates. Then at some point you realize that the implementation should be a little bit different, and then is hard to change all the implementations (duplicate code) you have. The C alternatives to solve this problem are not so easy as well. But I would like to hear other opinions about this. |
legalize+jeeves@mail.xmission.com (Richard): Jul 23 03:40PM [Please do not mail me a copy of your followup] Thiago Adams <thiago.adams@gmail.com> spake the secret code >I would like to understand better what you want to say. >More abstract code scale better? How? Maybe because you can >do the same think in less lines of code? C only has two facilities for abstraction: the struct and the function. While it is possible to build abstract data types on top of these two things (e.g. every "handle" based API in existence), the language doesn't really help you out. You can't do things like use 3D vectors or 3D points naturally with transformation matrices. (I often work in the 3D graphics problem domain.) Everything has to be written in terms of function calls instead of the natural notation of the problem space. This is one of the problem domains that is very "mathematical" in nature and overloading the arithemetic operators makes very good sense. Even outside of a mathematically oriented problem domain, I can't express object-oriented relationships between concepts directly in C. I have to invent my own virtual function mechanism using function pointers and the whole thing is very fragile. It can be done, but it requires significant programmer discipline in order to avoid bugs due to the manual nature of the mechanisms that you must use in C because the language doesn't support the construct directly. A good example is the abstractions in the X Window System server -- everything is done in an object-oriented way *by hand* because the server was written in C in order to obtain the most portability at the time. (The Xserver predates widespread adoption of C++.) >I believe C can scale well. (Maybe SOs are a good sample?) It can be done, but the language doesn't support sufficient abstraction mechanisms in order for the scaling to be done well. >build a container (like map something like that) and >then you have to duplicate the code and create other >containers because you don't have templates. Yes, this is another example where C has insufficient abstraction mechanisms to avoid code duplication, but this is not the kind of scaling I'm talking about. -- "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> |
legalize+jeeves@mail.xmission.com (Richard): Jul 23 03:44PM [Please do not mail me a copy of your followup] Cholo Lennon <chololennon@hotmail.com> spake the secret code >My problem with CLion (and Eclipse CDT) is the slow code indexing, it's >really slow. Qt Creator and Visual Studio don't have this problem. I use >CMake in all cases. They continue to improve it over time. However the consequence of the extensive indexing is that the refactoring is much more accurate than other tools. ReSharper for C++ and CLion routinely get the best scores on my refactoring test suite[1]. I don't know how much of the slowness is due to the implementation being in Java/C#. It's a "road not taken" hypothesis and the only way to get a fair measurement would be to reimplement the entire system in C++ and spend a lot of time tuning the C++. I guarantee you that they spend time tuning the IDE and improve it over time as I have witnessed many improvements over time. I used CLion on the LLVM/clang codebase, which is *huge*. This was a couple years ago, so I haven't tested more recent builds but I expect them to be much faster. [1] <https://github.com/LegalizeAdulthood/refactor-test-suite> -- "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> |
legalize+jeeves@mail.xmission.com (Richard): Jul 23 03:45PM [Please do not mail me a copy of your followup] Cholo Lennon <chololennon@hotmail.com> spake the secret code >with big Java projects. What is more, I don't know why CLion and Eclipse >CDT perform a full reindex every time I open a project, that's >unnecessary IMO :-O File bugs. JetBrains is much more responsive to my bug reports than other software vendors. -- "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> |
jacobnavia <jacob@jacob.remcomp.fr>: Jul 23 08:41PM +0200 Le 23/07/2018 à 17:40, Richard a écrit : > build a container (like map something like that) and > then you have to duplicate the code and create other > containers because you don't have templates. Look at the C containers library. The code is available for free at: https://github.com/shiva/ccl I use simply a set of macros to define a container for any type <T> jacob navia |
Thiago Adams <thiago.adams@gmail.com>: Jul 23 12:56PM -0700 On Monday, July 23, 2018 at 3:41:41 PM UTC-3, jacobnavia wrote: > https://github.com/shiva/ccl > I use simply a set of macros to define a container for any type <T> > jacob navia I already sent my comments on comp lang c for this lib some time ago. |
jacobnavia <jacob@jacob.remcomp.fr>: Jul 23 10:14PM +0200 Le 23/07/2018 à 21:56, Thiago Adams a écrit : >> jacob navia > I already sent my comments on comp lang c for this lib > some time ago. I do not remember all threads you started, sorry. I told you that "some time ago"... :-) In any case, for the people that do not read that threads, care to comment? |
legalize+jeeves@mail.xmission.com (Richard): Jul 23 08:38PM [Please do not mail me a copy of your followup] jacob@jacob.remcomp.fr spake the secret code >> build a container (like map something like that) and >> then you have to duplicate the code and create other >> containers because you don't have templates. Nit: I didn't write the above. -- "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> |
Vir Campestris <vir.campestris@invalid.invalid>: Jul 16 09:46PM +0100 > Given C doesn't have exceptions but only explicit returns then remembering > to call free on a local pointer is hardly onorous. Suppose we have a complex function, that allocates several things, performs checks on the way, and bails out when it doesn't like a result. Then suppose you want to re-order the checks. You then have to edit the cleanup before each return: bool dosomething { // block 1 type * a = new type; some checks if error { free a ; return false; } // block 2 type b = new type; some more checks if error { free a ; free b ;return false; } some more code free a; free b; return true } Now swap block 1 and block 2 around. Don't forget to edit the free statements. The only way I've seen that maintains your sanity is the Linux kernel way - use goto as an exception. bool dosomething { type * a = null; type * b = null; bool ret; a = new type; some checks if error { ret = false; goto error } b = new type; some more checks if error { ret = false; goto error } some more code ret = true; error: free a; free b; return ret; } Compare C++ bool dosomething { unique_ptr<type> a = std::make_unique<type>(); some checks if error return false; // block 2 unique_ptr<type> b = std::make_unique<type>(); some more checks if error return false; some more code return true } Andy |
Vir Campestris <vir.campestris@invalid.invalid>: Jul 16 09:49PM +0100 On 16/07/2018 18:23, Paavo Helde wrote: > That's true. Compilation time is my main complaint about C++. We use a thing called Icecream https://github.com/icecc/icecream It spreads the compile load around the office. I normally run my makes with -J128 - any higher than that and idon't gain, as it takes too long to send the work out. We have over 300 cores in the pool in our little branch office. Andy |
bitrex <user@example.net>: Jul 19 01:42PM -0400 >> So removing something that has no cost is a sound engineering decision? > There's no such thing as no cost in creating and destructing objects no matter > how slimline they may be and smart pointers are objects. If a unique_ptr object has no persistent state other than the wrapped pointer itself, which is the same persistent state the equivalent smart-pointer-free code would have, and the rest of the object's behavior is simply no different than the effect of writing "new" and "delete" at the appropriate times (or malloc/free in C) then that is precisely what the compiler will do and that's what the compiler will generate. What sense would it make to do anything else? |
bitrex <user@example.net>: Jul 19 01:46PM -0400 >> So removing something that has no cost is a sound engineering decision? > There's no such thing as no cost in creating and destructing objects no matter > how slimline they may be and smart pointers are objects. You're laboring under the assumption that every time you write Object object; in your code the compiler is actually producing code to execute constructors (that may do nothing at all), jump into destructors (that may do nothing at all), making stack allocations, assigning-immediate class member variables, running all around doing this and that. Every time. That isn't how modern optimizing compilers work. |
Bart <bc@freeuk.com>: Jul 16 10:40PM +0100 On 16/07/2018 22:20, Stefan Ram wrote: > { println( java.lang.Character::isJavaIdentifierStart ); > println( Main::identbody ); }} > transcript It's a mystery how you get from the above to the following: > $ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz > $0123456789ABCDEFGHIJKLMNOPQRSTUVWXY_abcdefghijklmnopqrstuvwxyz This is why expressiveness in the code is important - within reason otherwise too much will become cryptic. Even with the C code you can see where and how the 'A' to 'Z' range was defined. (The default printing I use only shows numbers, but will work out the ranges: [36,65..90,95,97..122] [36,48..57,65..89,95,97..122] This is handy for rather larger sets: println [1..1000'000'000] Output: [1..1000000000] which would otherwise take too long to print.) -- bart |
Bo Persson <bop@gmb.dk>: Jul 18 12:26PM +0200 On 2018-07-18 11:23, Ralf Fassel wrote: > IMHO in the above the DTOR of X should always get called regardless of > F() throwing or not. > R' No, main is not special (in this regard). The difference is having a try-catch, or not. Implementations are allowed to first go looking for the catch clause, and only then run the destructors for the stack objects. Or it could unwind one stack frame at a time while searching for the catch-clause. Makes a difference if the is NO try-catch in the current line of execution, so that the thrown exception leaves main. Could mean that the program is just terminated without executing any destructors. Bo Persson |
Paavo Helde <myfirstname@osa.pri.ee>: Jul 18 06:58PM +0300 On 18.07.2018 16:04, Thiago Adams wrote: > It must have some overhead in size because it has to build > the "landing pads" and tables state->landing pads. Yes, it trades some disk space for speed, but the size of executables does not interest most people nowadays (except some nutwits in this group). > Also it has to change some state (let's say change one pointer, > I don't known) while the code is completing ctors. In principle the state of the IP (instruction pointer) could be enough, don't know how it is actually done. > stack unwinding, but the document [1] says it uses > compression. The compression means that the states > table can be large. I believe they deal with relative jump offsets which are typically small numbers, so they are compressing away the high-order zero bytes. Can probably give something like 8x compression. Decompressing is a bit tedious but as this happens on the exceptional code path only it does not matter. |
scott@slp53.sl.home (Scott Lurndal): Jul 18 05:06PM >> does not interest most people nowadays (except some nutwits in this group). >Caring about the size of your executables pays off in >terms of runtimes and build times. Nonsense. > This talk by Mark >Zeren at Cppnow is a little vindication for the nutwits. Who is Mark Zeren, and why should I care? >https://duckduckgo.com/?q=cppnow+matters&t=h_&ia=videos&iax=videos&iai=vGV5u1nxqd8 Sorry, can't do videos and don't do duckduckgo. Post the actual link to words instead of the search terms. |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jul 19 10:36PM +0100 On 19/07/2018 22:12, Thiago Adams wrote: > that will always be used together because they depend on > each other to build and they can be reused in other > projects just coping the folder. Is this a deliberate troll? I sincerely hope so as the alternative is too depressing to think about. /Flibble -- "Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Bryne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?" "I'd say, bone cancer in children? What's that about?" Fry replied. "How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil." "Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say." |
ram@zedat.fu-berlin.de (Stefan Ram): Jul 16 08:53PM >But to go back to an earlier point, this sort of stuff really belongs in >a higher level language (higher level than C++) main.pl6 my $identstarter =( 'A' .. 'Z', 'a' .. 'z', '_', '$' ).Set; my $identbody =( $identstarter ∪ ( '0' .. '9' ))∖( 'Z' ); say $identstarter; say $identbody; transcript set($ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z) set($ 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y _ a b c d e f g h i j k l m n o p q r s t u v w x y z) ASCII version my $identstarter =( 'A' .. 'Z', 'a' .. 'z', '_', '$' ).Set; my $identbody =( $identstarter (|) ( '0' .. '9' ) ) (-) ( 'Z' ); say $identstarter; say $identbody; |
% <Persent@gmail.com>: Jul 18 06:23AM -0700 On 2018-07-17 3:32 AM, Storage Unit wrote: > those paths contain non-ASCII characters. >> Microsoft has been reliant on hard-coded paths since before Windows, >> and Windows 10 is no different. then why aren't you using 10 |
gof@somewhere.invalid (Adam Wysocki): Jul 19 12:25PM > Somebody posted on comp.lang.asm.x86 an algorithm for fizz buzz. There are many language tricks and hacks to make the solution interesting, but I prefer solutions that are readable and simple enough to do the task. The cleanest (definitely not the shortest) solution I could come up with (in C++): #v+ #include <boost/format.hpp> #include <iostream> static const unsigned MIN_NUMBER = 1; static const unsigned MAX_NUMBER = 100; /** * \brief Check if value is divisible by another value * * \retval true Dividend is divisible by divisor * \retval false Value is not divisible by divisor */ static inline bool isDivisible(unsigned dividend, unsigned divisor) { return !(dividend % divisor); } /** * \brief Make word according to FizzBuzz rules * * Returns word according to FizzBuzz rules, that is: * * - if value is divisible by 3 and not by 5, returns "Fizz" * - if value is divisible by 5 and not by 3, returns "Buzz" * - if value is divisible both by 3 and 5, returns "Fizz Buzz" * - as the last resort, returns string containing the value * * \param number Number to check * \return String according to FizzBuzz rules */ static std::string makeWord(unsigned number) { std::string word; if (isDivisible(number, 3)) word += "Fizz"; if (isDivisible(number, 5)) { if (!word.empty()) word += " "; word += "Buzz"; } if (word.empty()) word = boost::str(boost::format("%u") % number); return word; } int main() { for (unsigned i(MIN_NUMBER); i <= MAX_NUMBER; ++i) { const std::string suffix(i != MAX_NUMBER ? ", " : "\n"); std::cout << makeWord(i) << suffix; } return 0; } #v- -- [ Adam Wysocki :: Warsaw, Poland ] [ Email: a@b a=grp b=chmurka.net ] [ Web: http://www.chmurka.net/ ] |
Bo Persson <bop@gmb.dk>: Jul 19 08:19PM +0200 On 2018-07-19 16:06, Thiago Adams wrote: > p2 = std::move(p1); > in this case, the compiler would be allowed to remove > the destructor call of the p1. You know, perhaps it already does that? Here is the result on MSVC 2017: #include <memory> int main() { 00007FF7893D1000 sub rsp,28h std::unique_ptr<int> p1 = std::make_unique<int>(); 00007FF7893D1004 mov ecx,4 00007FF7893D1009 call operator new (07FF7893D1024h) 00007FF7893D100E xor ecx,ecx 00007FF7893D1010 mov dword ptr [rax],ecx std::unique_ptr<int> p2; p2 = std::move(p1); } 00007FF7893D1012 lea edx,[rcx+4] 00007FF7893D1015 mov rcx,rax 00007FF7893D1018 call operator delete (07FF7893D1060h) 00007FF7893D101D xor eax,eax 00007FF7893D101F add rsp,28h 00007FF7893D1023 ret What destructor call do you want to remove? Bo Persson |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jul 20 12:23AM +0200 This can cause an exception or possibly just a crash or UB, in Windows: std::locale{ setlocale( LC_ALL, nullptr ) } Full example program: ------------------------------------------------------------------------- #include <iostream> #include <locale> #include <locale.h> #include <stdexcept> #include <stdlib.h> auto main() -> int { setlocale( LC_ALL, "" ); // Default national locale (UTF-8 in *nix) setlocale( LC_NUMERIC, "C" ); // Periods as fraction separators, please. std::cout << "C level locale = \"" << setlocale( LC_ALL, nullptr ) << "\"\n"; try { const auto& loc = std::locale{ setlocale( LC_ALL, nullptr ) }; std::cout << "C++ level locale = " << loc.name() << "\n"; return EXIT_SUCCESS; } catch( std::exception const& x ) { std::cerr << "!" << x.what() << "\n"; } catch( ... ) { std::cerr << "!!! non-standard exception\n"; } return EXIT_FAILURE; } ------------------------------------------------------------------------- Results with respectively Visual C++ and MinGW g++, in that order: ------------------------------------------------------------------------- [P:\temp] > cl locale-sabotage.cpp /Feb locale-sabotage.cpp [P:\temp] > b C level locale = "LC_COLLATE=Norwegian Bokmål_Svalbard and Jan Mayen.1252;LC_CTYPE=Norwegian Bokmål_Svalbard and Jan Mayen.1252;LC_MONETARY=Norwegian Bokmål_Svalbard and Jan Mayen.1252;LC_NUMERIC=C;LC_TIME=Norwegian Bokmål_Svalbard and Jan Mayen.1252" C++ level locale = LC_COLLATE=Norwegian Bokmål_Svalbard and Jan Mayen.1252;LC_CTYPE=Norwegian Bokmål_Svalbard and Jan Mayen.1252;LC_MONETARY=Norwegian Bokmål_Svalbard and Jan Mayen.1252;LC_NUMERIC=C;LC_TIME=Norwegian Bokmål_Svalbard and Jan Mayen.1252 [P:\temp] > g++ locale-sabotage.cpp [P:\temp] > a C level locale = "LC_COLLATE=Norwegian Bokmål_Svalbard and Jan Mayen.1252;LC_CTYPE=Norwegian Bokmål_Svalbard and Jan Mayen.1252;LC_MONETARY=Norwegian Bokmål_Svalbard and Jan Mayen.1252;LC_NUMERIC=C;LC_TIME=Norwegian Bokmål_Svalbard and Jan Mayen.1252" !locale::facet::_S_create_c_locale name not valid ------------------------------------------------------------------------- This is in Windows 10. I seem to remember that locale names were like "no_NB.1252", and not the long descriptive text above. Has something changed? Because I also remember g++'s C++ level locale handling to be missing or screwed up, so that /could/ be the problem? Cheers!, - Alf |
Tim Rentsch <txr@alumni.caltech.edu>: Jul 18 10:55AM -0700 >> the requirements. > Maybe we should say in many cases, the TDD tests are the only form > of requirements... This statement confuses several significantly distinct notions, which in turn confuses the issue. The /requirements/ of a desired program are all those things that need to be true in order for the program to be useful in accomplishing its intended purpose. These things may be called the actual or true requirements. A /statement of requirements/ is what results from an effort to capture those things in a verbal (usually written) form. A key difference is that we know what is included in a statement of requirements, but often don't know what is included in the actual requirements, because customers often aren't sure or don't understand what is really needed. An effort to establish that a statement of requirements matches the actual requirements is called validation (in particular, in the software world it is called software validation). An effort to establish that a program's behavior matches its statement of requirements is called software verification. Informally, the phrases "build the right thing" and "build the thing right" are sometimes used for validation and verification, respectively. A set of tests written (under any methodology) to help establish program behavior, under certain circumstances, generally falls into the category of verification. Some of those tests -- in particular, those that check end-to-end externally visible program behavior -- might correspond to parts of a statement of requirements. In contrast, internal tests might be useful in helping verify a program's behavior, but they never belong in a statement of requirements, because the customer doesn't care about how a program operates internally (or if they do, it means those predicates are not really internal conditions). Of course, a customer might agree, whether explicitly or not, that passing some set of tests (perhaps in addition to some other criteria) means the program is satisfactory as far as they are concerned. Any set of tests might be part of an acceptance measure. But being part of an acceptance measure doesn't mean a specific tested condition belongs in a statement of requirements necessarily. Moreover, even if a particular condition is agreed to be part of a statement of requirements, that doesn't change the actual requirements, which are not affected (even if not always knowable) by what the statement of requirements says. Bottom line, if after delivery a program never gets used to accomplish what the customer wanted to accomplish with it, the program has not met its requirements. It may be that it has met its contractual obligations, but that doesn't guarantee that it has met its actual requirements. |
Paavo Helde <myfirstname@osa.pri.ee>: Jul 18 08:49PM +0300 On 18.07.2018 19:57, Daniel wrote: > to return 10 or 20 depending on the size of the integer, or not compile if > the integer type is not 32 or 64 bits. > I'm having some difficulty solving this with SFINAE. Any suggestions? Something like this? #include <iostream> class A { int32_t value1_; int64_t value2_; private: template<int sz> struct traits { using type = void; }; template<> struct traits<4> { using type = int32_t; }; template<> struct traits<8> { using type = int64_t; }; template<int sz> typename traits<sz>::type Get() const; template<> traits<4>::type Get<4>() const { return value1_; } template<> traits<8>::type Get<8>() const { return value2_; } public: A() : value1_(10), value2_(20) {} template<typename T> explicit operator T() const { return Get<sizeof(T)>(); } }; int main() { A a; std::cout << (int32_t)a << ", " << (int64_t)a << std::endl; } |
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