- New address of the C Containers library - 8 Updates
- Function arguments and braced initializer lists - 1 Update
- std::initializer_list assignment operator - 2 Updates
- How to split a char array? - 9 Updates
- using static constexpr within static constexpr - 2 Updates
- Pointer on Pointer, or simple Pointer? - 3 Updates
Juha Nieminen <nospam@thanks.invalid>: Apr 04 07:13AM > https://github.com/jacob-navia/ccl.git I think this is a good demonstration of why C++ is, among other things, more memory-efficient than C. I did a quick test like this: //-------------------------------------------------------------- #include "ccl/intdlist.h" #include <list> #include <iostream> int main() { std::cout << sizeof(std::list<int>) << " " << sizeof(std::list<int>::iterator) << "\n" << sizeof(INTERFACE_STRUCT_INTERNAL_NAME(int)) << " " << sizeof(ITERATOR(int)) << "\n"; } //-------------------------------------------------------------- And the result was: 24 8 512 112 Of course the C++ version is not only more memory-efficient, it's also technically speaking faster because every std::list method call is a direct function call (that can ostensibly be even inlined by the compiler if it deems it efficient), while in the C version each call has an additional level of indirection, and the compiler has no possibility of inlining. --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
jacobnavia <jacob@jacob.remcomp.fr>: Apr 04 11:42AM +0200 Le 04/04/2016 09:13, Juha Nieminen a écrit : > additional level of indirection, and the compiler has no possibility > of inlining. > --- news://freenews.netfront.net/ - complaints: news@netfront.net --- It would be nice if you told us what are INTERFACE_STRUCT_INTERNAL_NAME and ITERATOR. Thanks |
jacobnavia <jacob@jacob.remcomp.fr>: Apr 04 11:57AM +0200 Le 04/04/2016 09:13, Juha Nieminen a écrit : > And the result was: > 24 8 > 512 112 I compiled this program IN C!! #include "containers.h" #include "ccl_internal.h" int main(void) { printf("sizeof(Dlist)=%lu\n",sizeof(Dlist)); } Result: ~/ccl/test $ ./a.out sizeof(Dlist)=96 96 is not 512. You have made a mistake: you compiled the program with a C++ compiler. Use a C compiler instead. You say: << Of course the C++ version is not only more memory-efficient, it's also technically speaking faster because every std::list method call is a direct function call The difference between a direct and an indirect call is just ONE MEMORY ACCESS. Does a single memory access make ANY difference at 2.7GB/second? Of course not. C offers the added flexibility (that you loose when the call is hard-wired like in C++) that you can change the call at run time if you want. You say: << in the C version each call has an additional level of indirection, and the compiler has no possibility of inlining. Of course the compiler could inline IF THE COMPILER WRITERS WANTED. But since C is not being developed anymore as a language (only C++ counts) this optimizations aren't offered. You could install a "freeze" switch in the compiler that would it allow to inline calls through a known function pointer assuming the function pointer is fixed at the start of the program. |
Ian Collins <ian-news@hotmail.com>: Apr 04 10:01PM +1200 On 04/04/16 21:57, jacobnavia wrote: > C offers the added flexibility (that you loose when the call is > hard-wired like in C++) that you can change the call at run time if you > want. The interesting question is when would you want to change the call? -- Ian Collins |
jacobnavia <jacob@jacob.remcomp.fr>: Apr 04 12:06PM +0200 Le 04/04/2016 12:01, Ian Collins a écrit : >> hard-wired like in C++) that you can change the call at run time if you >> want. > The interesting question is when would you want to change the call? This allows a dynamic subclassing of some features of an interface. For instance a hash table adapted to ALL possible sizes of data is probably not 100% good at small sizes and also at huge sizes. According to the dynamic requirements of the program, you can change the search, or insert functions of an interface to adapt it to a huge/small container. Obviously if you can do it at compile time is better, but that is not always possible, specially if it is a library... |
Keith Thompson <kst-u@mib.org>: Mar 30 09:23AM -0700 (I'm not sure this belongs in comp.lang.c++, but I'll leave the newsgroups list as it is for now.) >> There you will find all the source code and the source code of the >> dopcumentation in TeX form (the only word processor of the 80es that is >> still running today and will run in 2030) [...] > Thanks for the warning. > Out of curiosity, is it really written in plain C, or that 'almost C' > flavor you like? It appears to be plain C. When I modify the Makefile to use -std=c11 -pedantic -Wall -Wextra -O3 with gcc 5.3.0, I get a number of unused parameter warnings. (I haven't looked into them, but that's probably to be expected for this kind of thing.) Adding -Wno-unused-parameter leaves two warnings: hashtable.c: In function 'Clear': hashtable.c:696:27: warning: 'HashIdx.ht' is used uninitialized in this function [-Wuninitialized] if (hi->index > hi->ht->max) ^ hashtable.c:383:15: note: 'HashIdx' was declared here HashIndex HashIdx,*hi; ^ and: priorityqueue.c: In function 'checkcons': priorityqueue.c:418:36: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] if (h->Log2N == -1 || h->count > (1 << h->Log2N)) { "-std=c99" gives similar results. One more minor problem: "make clean" doesn't remove "test.o". -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
scott@slp53.sl.home (Scott Lurndal): Mar 30 03:11PM >There you will find all the source code and the source code of the >dopcumentation in TeX form (the only word processor of the 80es that is >still running today and will run in 2030) troff is a word processor of the 70's that is still running today, and will continue to run through 2030, and is still the foundation of manual pages on unix/linux systems. If you are documenting source code, then you should at minimum provide doxygen comments in the source. |
jacobnavia <jacob@jacob.remcomp.fr>: Mar 30 06:01PM +0200 Le 30/03/2016 17:11, Scott Lurndal a écrit : > the 70's that is still running today, and will continue to > run through 2030, and is still the foundation of manual pages > on unix/linux systems. You are comparing TeX to troff? How about mathematical formulae? How about QUALITY? Please, there is NO comparison here! |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 31 08:35PM -0500 > Therefore, argument passing is more fundamental than > assignment expressions, so one cannot use assignment > expressions to explain argument passing in a strict text. You appear to be confusing assignment with something that is not assignment. /Flibble |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 04 05:41AM >I am curious to see how the initializer_list assignment >operator looks like but I can't find its code in the STL >library. 5.18p9: A braced-init-list may appear on the right-hand side of an assignment to a scalar, in which case the initializer list shall have at most a single element. The meaning of x={v}, where T is the scalar type of the expression x, is that of x=T{v}. The meaning of x={} is x=T{}. A braced-init-list may appear on the right-hand side of an assignment to an object of class type, in which case the initializer list is passed as the argument to the assignment operator function selected by overload resolution (13.5.3, 13.3). (I am still wondering whether the last paragraph also does not exclude the possibility that no such assignment operator function exists, but there is a type conversion available from the type of the initializer list as an expression to the type of the right hand side.) |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 01 01:10AM >void print( ::std::string s ){ ::std::cout << s << '\n'; } >int main() >{ print( "alpha" ); And while I'm at it: Did I got this right: The initialization of the parameter s above by the argument "alpha" (or any other argument expression) is as if by ::std::string s = "alpha"; ? Or for the call »print( { { "alpha" }} )« as if by ::std::string s = { { "alpha" }}; ? This seems to be confirmed by the following program having similar results as the OP program: #include <iostream> #include <string> int main() { { ::std::string s = "alpha"; } { ::std::string s = { "alpha" }; } { ::std::string s = { { "alpha" }}; } /* { ::std::string s = { { { "alpha" }}}; } */ /* No! */ } However, in the C++ standard it is the other way round for user-defined class types: The effect of an assignment is being defined by passing the operands to an appropriate assignment operator function. Therefore, argument passing is more fundamental than assignment expressions, so one cannot use assignment expressions to explain argument passing in a strict text. |
Juha Nieminen <nospam@thanks.invalid>: Apr 04 06:17AM > If you have only used std::list once in your entire career then it is > painfully obvious that you are not aware of (or stubbornly ignore) its > advantages. I am perfectly aware of its properties. I have never needed it. > std::set, std::multiset, std::map and std::multimap also have a single > node based allocation strategy so are you suggesting we shouldn't use > these containers either as they are "slow"? I was comparing std::list to std::vector and std::deque. std::set & co. have advantages that std::list does not have, and those are useful in certain situations. I have yet to encounter a practical situation where std::list would be more useful than eg. std::vector. --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
Juha Nieminen <nospam@thanks.invalid>: Apr 04 06:19AM > You can use a custom allocator with std::list to avoid fragmentation; > without a custom allocator std::deque also suffers from fragmentation. std::deque is a lot faster than std::list when adding elements to the beginning or end, without the need for any custom allocators. Even *with* a custom allocator, I doubt std::list would become even equally fast. --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
Ian Collins <ian-news@hotmail.com>: Apr 04 06:24PM +1200 On 04/04/16 18:17, Juha Nieminen wrote: > std::set & co. have advantages that std::list does not have, and those > are useful in certain situations. I have yet to encounter a practical > situation where std::list would be more useful than eg. std::vector. Implementing a queue? -- Ian Collins |
Mr Flibble <flibble@i42.co.uk>: Apr 04 12:15PM +0100 On 04/04/2016 07:19, Juha Nieminen wrote: > beginning or end, without the need for any custom allocators. > Even *with* a custom allocator, I doubt std::list would become even > equally fast. You are missing the point: std::deque and std::list have different use-cases; your problem is that you are blissfully unaware of the std::list use-cases. /Flibble |
SG <s.gesemann@gmail.com>: Apr 04 04:37AM -0700 On Monday, April 4, 2016 at 1:16:18 PM UTC+2, Mr Flibble wrote: > [...] > std::list use-cases. Out of curiosity: Name one. Cheers! sg |
Mr Flibble <flibble@i42.co.uk>: Apr 04 12:46PM +0100 On 04/04/2016 12:37, SG wrote: >> [...] >> std::list use-cases. > Out of curiosity: Name one. Any time you need element identity. /Flibble |
Paavo Helde <myfirstname@osa.pri.ee>: Mar 30 11:15PM +0200 On 30.03.2016 21:04, Heinz-Mario Frühbeis wrote: > I know, what I experience... std::string.c_str works, std::string not. Sorry, with C++ this is not sufficient. You have to know whether and why something works and something does not. If you do not know and do not want to learn, please choose another language, with less Undefined Behavior. Cheers Paavo |
Mr Flibble <flibble@i42.co.uk>: Mar 30 09:23PM +0100 On 30/03/2016 20:59, Dombo wrote: >> "efficiency" (complexity) is concerned. > But it does make a difference as far as effective speed and memory > fragmentation is concerned. You can use a custom allocator with std::list to avoid fragmentation; without a custom allocator std::deque also suffers from fragmentation. /Flibble |
SG <s.gesemann@gmail.com>: Apr 04 06:25AM -0700 On Monday, April 4, 2016 at 1:47:06 PM UTC+2, Mr Flibble wrote: > >> std::list use-cases. > > Out of curiosity: Name one. > Any time you need element identity. You can get "element identity" in many ways. A collegue of mine relies on "element identity" but uses std::deque. As long as you only add/ remove elements at/from the beginning or end, references will stay valid. std::deque gives you a memory layout that's not too bad without having to use a custom allocator and it offers random access. And then there are things like Boost's ptr_vector giving you "element identity" as well, even supporting polymorphism. In what situations would you prefer std::list and why? Could you be a little more specific? Cheers! sg |
Robert Wessel <robertwessel2@yahoo.com>: Apr 04 12:21AM -0500 On Sun, 3 Apr 2016 17:25:37 -0400, bitrex >contents of the array to be evaluated at compile time via the first >"constexpr." >Is there a way to get at what I'm getting at? Is the definition of blarg() constexpr? |
bitrex <bitrex@de.lete.earthlink.net>: Apr 04 08:50AM -0400 On 04/04/2016 01:21 AM, Robert Wessel wrote: > Is the definition of blarg() constexpr? blarg should = bar...made a mistake when typing up my dummy names... |
"Heinz-Mario Frühbeis" <Div@Earlybite.individcore.de>: Apr 04 10:19AM +0200 Hi, can I use these functions as [1]? [1] Display* Dispplay_Open(){ return XOpenDisplay(NULL); } int Display_Close(Display *vDisplay){ return XCloseDisplay(vDisplay); } void Test(){ Display *nDisplay = NULL; nDisplay = Display_Open(); Display_Close(nDisplay); } Or do I need to use a pointer on a pointer? [2] int Display_Close(Display **vDisplay){ return XCloseDisplay(*vDisplay); } void Test(){ Display *nDisplay = NULL; nDisplay = Display_Open(); Display_Close(&nDisplay); } TIA Heinz-Mario Frühbeis |
Ian Collins <ian-news@hotmail.com>: Apr 04 08:26PM +1200 On 04/04/16 20:19, Heinz-Mario Frühbeis wrote: > int Display_Close(Display **vDisplay){ > return XCloseDisplay(*vDisplay); > } Given XCloseDisplay() takes a Display*, why would you need a pointer to pointer? The only reason to do this is if you are going to modify the parameter value. -- Ian Collins |
"Heinz-Mario Frühbeis" <Div@Earlybite.individcore.de>: Apr 04 11:51AM +0200 Am 04.04.2016 um 10:26 schrieb Ian Collins: > Given XCloseDisplay() takes a Display*, why would you need a pointer to > pointer? The only reason to do this is if you are going to modify the > parameter value. Ok, thanks. Regards Heinz-Mario Frühbeis |
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