- "constexpr" everywhere? - 3 Updates
- Returning Function Pointers - 2 Updates
- Code for destructor of linked list - 4 Updates
- Onwards and upwards - 2 Updates
- "constexpr" everywhere? - 3 Updates
- How to call the unary "::"? - 1 Update
- Function Objects - 1 Update
ram@zedat.fu-berlin.de (Stefan Ram): May 03 11:59AM >pointless to use 'constexpr' just to detect if a constructor >or function matches with (quite loose in C++14) requirements >for those. When a function or constructor is declared with »constexpr«, the compiler will choose to calculate it at compile time when feasible. This will never hurt (?) and sometimes speed up program execution, since some values do not have to be calculated at run time. So one should always use »constexpr« when possible. /Not/ because we can thus detect whether C++ requirements are fulfilled, /but/ because we want the program to run as fast as possible! In the special case of »complex«, there is an additional reason: A complex number should behave as similar to a double as possible. Since »double« is a "literal type" we want complex to be a "literal type" too. |
ram@zedat.fu-berlin.de (Stefan Ram): May 03 04:02PM >There is no "problem" with it, if it works (theoretically) and >accomplishes what you mean it to accomplish. However, as you can >probably judge, it's recursive, (Disclaimer: I never wrote a destructor and I never wrote a »delete« call, so the following might be utter nonsense:) The »delete head« deletes the next node and, IIRC, that will (recursively) invoke the destructor for the next node. So, there is no need for the while loop! So, one should decide whether a recursive solution is wanted. if so, one can eliminate the redundant »while«. Otherwise, an iterative solution might be possible by setting »head->next = 0;« after it has been saved, so that the »delete head;« will not continue to recurse. |
ram@zedat.fu-berlin.de (Stefan Ram): May 03 04:39PM I posted this program into another newsgroup, where the topic was how short a program to calculate a product of sums of values can be in various programming languages: #include <iostream> #include <ostream> #include <initializer_list> int main() { auto const X ={ 1, 2 }; auto const Y ={ 3, 4 }; double r = 1.0; for( int const x : X )for( int const y : Y )r *= x + y; ::std::cout << r << '\n'; } . Then, I wondered how short I can make it when I do not follow my usual stylistic guidelines. The following still works under the C++ implementation used: #include <iostream> int main() {auto X={1,2},Y={3,4},r=1;for(int x:X)for(int y:Y)r*=x+y;std::cout<<r;} But why is auto X={1,2},Y={3,4},r=1; actually possible? The type deduced for »{1,2}« should be «initializer_list<int>«, while the type deduced for »r« should be »int«, so it's not the same type! (If you would write »r=1.«, then the implementation /would/ complain that the types do not match.) |
legalize+jeeves@mail.xmission.com (Richard): May 03 02:18AM [Please do not mail me a copy of your followup] Doug Mika <dougmmika@gmail.com> spake the secret code >Well, I found something on function pointers, but id didn't cover how it >looks when your function returns these. >That is, until I found the following piece of code I attach below What you found in a piece of C code. Please don't code C in C++. Use C++ mechanisms and abstractions to achieve your purposes instead of C mechanisms and its limited abstractions. Function pointers are how C achieves variability of function, but C++ has better mechanisms: classes, virtual methods and templates to name just a few. Function pointer syntax gets ugly quite quickly, which is one of the reasons that people often use them with typedefs in order to make things sane again. If you just use the abstraction mechanisms in C++ instead, you can return to normalcy. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Permil Garg <garg.permil@gmail.com>: May 03 09:25AM -0700 > {OPER_TAN, tan}, > {OPER_SQUARE, square}, > }; This is a array of struct (oper) which named oper_lut[] and it is initialized with 4 values. In braces, the value of array to initialize. Before (,) is the enum value and after (,) is function name. |
Paul <pepstein5@gmail.com>: May 03 02:51AM -0700 No, this is not for a homework or class assignment. I am trying to learn this stuff independently. The below is my attempt to write a destructor for a linked list. I'm suspicious of it because it seems different and somewhat simpler than the answers I've seen online. I'd be grateful if someone could tell me if there's a problem with it. Thank you. Paul struct LinkedList { int data; LinkedList* next; ~LinkedList(); }; LinkedList::~LinkedList() { while(next) { LinkedList* head = next; next = head->next; delete head; } } |
Victor Bazarov <v.bazarov@comcast.invalid>: May 03 11:35AM -0400 On 5/3/2015 5:51 AM, Paul wrote: > No, this is not for a homework or class assignment. I am trying to learn this stuff independently. > The below is my attempt to write a destructor for a linked list. I'm suspicious of it because it seems different and somewhat simpler than the answers I've seen online. I'd be grateful if someone could tell me if there's a problem with it. Thank you. > delete head; > } > } There is no "problem" with it, if it works (theoretically) and accomplishes what you mean it to accomplish. However, as you can probably judge, it's recursive, and that could mean a problem if your linked list grows to be too long for the execution environment to handle. You're going to learn about it eventually, so you might start now. Recursion is usually organized using the process' stack (automatic storage), which is often limited. In order to avoid putting too much stress on the stack, it is advisable to replace recursion with a loop whenever possible. I'll leave it to you to convert this recursive function into a proper loop. V -- I do not respond to top-posted replies, please don't ask |
Paavo Helde <myfirstname@osa.pri.ee>: May 03 11:05AM -0500 Paul <pepstein5@gmail.com> wrote in > next = head->next; > delete head; > } It seems you are trying to delete everyhing twice ('delete head' already deletes head->next recursively so there is no need for the while loop). Double-deleting a pointer is illegal, so the program is invalid. On the other hand, deleting a NULL pointer is a well-defined non-op, so in principle you could have even simpler constructor: LinkedList::~LinkedList() { delete next; } However, this is a recursive call, which may cause troubles (stack overflow) with huge lists, so a while loop would be in principle better. Alas, your variant of it was invalid. Cheers Paavo |
Melzzzzz <mel@zzzzz.com>: May 03 06:06PM +0200 On Sun, 03 May 2015 11:35:03 -0400 > > } > > } > There is no "problem" with it, if it works (theoretically) It does not works... |
woodbrian77@gmail.com: May 02 09:20PM -0700 http://www.dailymail.co.uk/sciencetech/article-3064915/Is-internet-brink-collapse-web-reach-limit-just-eight-years-warn-engineers.html The article says, "Storing information in large 'server farms', rather than transferring it, would take the strain off the network." This is the approach I've taken with the C++ Middleware Writer -- files are only copied across the network if they have been updated. I did this more to reduce bandwidth costs than thinking the internet was unstable. I hope this article will encourage people to consider their bandwidth consumption. Brian Ebenezer Enterprises - In G-d we trust. http://webEbenezer.net |
scott@slp53.sl.home (Scott Lurndal): May 03 03:30PM >transferring it, would take the strain off the network." > I hope this article will encourage people >to consider their bandwidth consumption. I would hope that article teaches people to be less gullible. The _Daily Mail_? Give me a break. >Brian >Ebenezer Enterprises - In G-d we trust. Never mind, too late. |
Bo Persson <bop@gmb.dk>: May 03 09:55AM +0200 On 2015-05-03 00:14, Stefan Ram wrote: > possible and there were comments that suggested this to him. > What do you think why he did not use »constexpr« at the > beginning of the constructors and some member functions? Perhaps he just didn't see any immediate use for compile time complex arithmetic? Bo Persson |
"Öö Tiib" <ootiib@hot.ee>: May 03 03:30AM -0700 On Sunday, 3 May 2015 01:14:19 UTC+3, Stefan Ram wrote: > beginning of the constructors and some member functions? > Could there be any drawback of using »constexpr«, when it > is possible? Even the latest betas of Microsoft compilers do not support 'constexpr' too well. Herb Sutter is lead architect of Microsoft C++ compilers so can not publish C++ code that puts those into bad light. > it might be difficult to change the interface later when, > for some reason, the constructor or function cannot be > implemented as constexpr any longer.) We should use 'constexpr' functions and constructors where we plan to use these for producing constant expressions. It is pointless to use 'constexpr' just to detect if a constructor or function matches with (quite loose in C++14) requirements for those. |
"Öö Tiib" <ootiib@hot.ee>: May 03 06:10AM -0700 On Sunday, 3 May 2015 14:59:27 UTC+3, Stefan Ram wrote: > when possible. /Not/ because we can thus detect whether C++ > requirements are fulfilled, /but/ because we want the > program to run as fast as possible! 'constexpr' does not make function to run compile time nor does lack of it guarantee that it does not run compile time so your point is moot. Besides how you teach software development without knowing at all what our work is about? First we want the program that we make to do what it should do. Second we want it to work as correctly as it is possible. Everything else (like speed of its run and such) is of secondary importance until those two goals have been met. Unfortunately these primary goals are most hard to reach. What it should do is often unknown (or more precisely imagined naively) even to its authors and stakeholders and what it does follows the requirements (even those naive interpretations) always incorrectly or imprecisely at least in some corner cases. So we typically gradually maintain it closer and closer to what it should actually do as our knowledge grows. Marking every function possible as 'constexpr' does not aid with neither of two primary goals and it only distracts during maintenance. Example: So we discover that we clearly need to add a try-catch into some function but originally it was marked as 'constexpr'. Why? Maybe author used it somewhere to make constant expressions. Remove it and rebuild. Half our later ... does not seem to be the case. Maybe code makes constant expressions with it under some other build options? Can't build all the configurations out of blue so lets see all the 1000 calls of it. Hours later ... no ... we may add try-catch. Author did put 'constexpr' there just to waste our time. > reason: A complex number should behave as similar to a > double as possible. Since »double« is a "literal type" we > want complex to be a "literal type" too. About why Herb Sutter designed 'complex' like he did I already answered and you snipped it. Can't you avoid bringing back discussions that you snipped? Here it goes again: "Herb Sutter is lead architect of Microsoft C++ compilers so he can not publish C++ code that puts those into bad light." |
Bo Persson <bop@gmb.dk>: May 03 08:31AM +0200 On 2015-05-02 16:39, Stefan Ram wrote: > ? The second »::« is the binary "scope resolution operator", > but is the first unary one also called "scope resolution > operator"? It really IS the same operator in both places. It just so happens that the global namespace has no name, so its position looks empty. Bo Persson |
"Öö Tiib" <ootiib@hot.ee>: May 02 06:04PM -0700 On Sunday, 3 May 2015 01:00:39 UTC+3, Paavo Helde wrote: > specifically fixed a gap in an area which prevented achieving maximum > performance in certain high-level programming style. It is under the > control of the programmer to use or not use this style. 'register' keyword did mean one day that variable will occupy a register. Now it only means that one may not take reference of the variable or parameter. 'inline' keyword did mean one day that the function should be inlined. Now it only means that defining the function several times copy-paste in the same program is not ODR violation. It is so because such decision gave better performance. Move semantics puts it into programmers hands to indicate if a value passed will end its duration for next anyway so it may be moved instead of copied. It may happen that it will be also decay into "hint" one day that is easier for compiler actually to decide (for better performance). > porton of programmers and programs would move away to some other language > to retain the maximum performance (to Fortran or C, possibly to something > else branched off from C++ (D?)). I did not mean that C++ is adding or should start adding any overhead. I mean that the programmers somehow manage to add complications and so cause overhead with anything. |
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