Monday, April 4, 2016

Digest for comp.lang.c++@googlegroups.com - 25 updates in 6 topics

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: