Wednesday, July 29, 2009

comp.lang.c++ - 25 new messages in 17 topics - digest

comp.lang.c++
http://groups.google.com/group/comp.lang.c++?hl=en

comp.lang.c++@googlegroups.com

Today's topics:

* How to write previous element in STL list - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/2d136691c93121bf?hl=en
* SSO - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/77f7c1c9190e45a7?hl=en
* strcpy vs memcpy - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/71a5945deead500c?hl=en
* static member variable - 4 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/e1a69a5a67723783?hl=en
* paypal payment)( www.guoshitrade.com )Discount Nike Jordan 21 Shoes
Manufacture - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/a02b5b1adbdc2be6?hl=en
* Chanal Bags wholesaler (paypal payment)( www.guoshitrade.com) - 1 messages,
1 author
http://groups.google.com/group/comp.lang.c++/t/ace73a421108f74e?hl=en
* ↖◆↗Fashion items in www.guoshitrade.com*-*-* wholesale Ed Jeans, Tshirts,BBC,
Gucci, Armani,Lacoste, Aff,Fashion items, Cheap!!!! - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/7156a2654a43c6d8?hl=en
* ✖Nike Jordan✖Your Best Choice Jordan1,1.5,2,2.5,3,3.5,4,4.5,­5,6,7,8,9,10,11,
12,13,14,15,16­,17,18,19,Jordan25+AF1 ,Jordan13+AJ6Rings ,Jordan9+Jordan23 Man,
Jordan3+Jordan5+Jordan15,,­etc Welcome To Visit Our Site www.guomeitrade.com
Paypal Paymet - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/8079625e640ea9f8?hl=en
* Reebok Baltimore Ravens Ray Lewis 2009 Pro Bowl AFC Replica Jersey (www.
guoshijerseys.com) - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/14c09553ab1529e0?hl=en
* Unique Identifiers - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/4a51924c25f7395a?hl=en
* (paypal payment)( www.guoshitrade.com ) wholesale DIESEL T-shirt - 1
messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/c249e76d320ff0b1?hl=en
* dealing with lower level programmers - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/f708a2c0cfa8ce2d?hl=en
* Behaviour of istream_iterator on closed stream - 3 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/b2854b7eb7f63001?hl=en
* Alternatives to C: ObjectPascal, Eiffel, Ada or Modula-3? - 2 messages, 2
authors
http://groups.google.com/group/comp.lang.c++/t/40783f7f814400c9?hl=en
* Tudor Watch wholesale (paypal payment) (www.guoshitrade.com ) - 1 messages,
1 author
http://groups.google.com/group/comp.lang.c++/t/5a059b6d6e960864?hl=en
* Discount rayban sunglasses www.guoshitrade.com - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/f3c454dfcde0688f?hl=en
* (paypal payment)( www.guoshitrade.com ) cheap wholesale,BRM ,shirt - 1
messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/fe56942508a85015?hl=en

==============================================================================
TOPIC: How to write previous element in STL list
http://groups.google.com/group/comp.lang.c++/t/2d136691c93121bf?hl=en
==============================================================================

== 1 of 1 ==
Date: Wed, Jul 29 2009 2:11 am
From: Juha Nieminen


James Kanze wrote:
> On Jul 28, 4:32 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
>> Pascal J. Bourguignon wrote:
>>> I don't know if the C++ standard does the same about operators such as
>>> +, but indeed it might be expect that + is a O(1) operation.
>
>> You can write your own operator+ for your list iterators if
>> you want. There's nothing stopping you. (Except that I think
>> you can't template operator overloads, which is a bit of a
>> bummer, but you can overload the operator for specific list
>> types.)
>
> Operator overloads can be template functions; there's no problem
> there. The problem for operator+ on an std::list::iterator is
> that if you try to write:
>
> template< typename T >
> typename std::list< T >::iterator
> operator+(
> typename std::list< T >::iterator
> lhs,
> int rhs )
> {
> std::advance( lhs, rhs ) ;
> return lhs ;
> }
>
> , T is in a non-deduced context, which means that template
> argument deduction fails, and no instantiation of the template
> is added to the overload set. (You can, of course, still call
> it with "::operator+<int>( i, 3 )", but that sort of defeats the
> purpose of operator overloading.) And if you just write:
>
> template< typename T >
> T
> operator+(
> T lhs,
> int rhs )
> {
> std::advance( lhs, rhs ) ;
> return lhs ;
> }
>
> , you're going to match a lot of things you don't want it to
> match, and probably cause problems elsewhere (ambiguous
> overloads, or it might even be a better match than the intended
> operator).

I suppose there is no way of implementing this in a templated way?

(I wonder if concepts would have helped doing this, if they had been
included in the next standard. Or were concepts usable purely for
compile-time diagnostics?)

==============================================================================
TOPIC: SSO
http://groups.google.com/group/comp.lang.c++/t/77f7c1c9190e45a7?hl=en
==============================================================================

== 1 of 2 ==
Date: Wed, Jul 29 2009 2:23 am
From: James Kanze


On Jul 29, 11:03 am, Juha Nieminen <nos...@thanks.invalid> wrote:
> tni wrote:
> >> What advantages does a string class with SSO have over one
> >> which always allocates the string dynamically and uses CoW?

> > Copying is much faster for small strings (at least on some
> > important platforms like x86).

> I don't see how that would be the case. With a regular CoW
> string a copy entails assigning one pointer and updating one
> counter at the end of that pointer. Copying a string which
> uses SSO entails a check whether the string is small or
> dynamically allocated, and then (assuming it is small) a copy
> of a member array (which is probably several times larger than
> a pointer) and the size member variable.

> I could even believe that with optimal cache behavior and such
> you could even achieve similar speeds, but much faster? I
> don't see that happening.

Fine grained locality plays a very large role. Most modern
processors access memory in more or less large chunks; when you
read the size (to test whether the local buffer is used or not),
the hardware also loads the local buffer at the same time, and
it's already in the pipeline when you start to copy it.

But IIRC, the real speed gain occurs in multi-threaded
environments. The fact that no part implementation is shared
means that no synchronization is required. And on modern
processors, synchronization is expensive. (On the other hand...
in the applications I've worked on, most of the strings are
large enough that the small string optimization wouldn't apply,
and dynamic allocation also requires synchronization, so
COW---even using pthread_mutex for synchronization---is still an
optimization if I'm copying strings a lot.)

> (And of course if the string was not small, but dynamically
> allocated, the copying will be basically identical except that
> there will be the additional check before copying.)

> > For COW, you generally need some form of reference counting
> > with atomic counters.

> The STL, at least the implementation in gcc, has never
> bothered with atomicity...

The implementation of std::string in g++ is not thread safe.

> > That's going to cost a few dozen clock cycles for a counter
> > access on x86 and causes the bus to be locked (which is a
> > very bad thing if you have lots of CPUs/cores). So, in a
> > highly parallel environment, you probably don't want COW.

> OTOH always deep-copying can be detrimental for speed in many
> situations, such as when sorting an array of large strings.
> I'd bet that even using locking would be faster.

I've wondered about that too. In most of my work, I'd guess
that the shortest strings are about 20 characters (more than the
SSO handles in most of the implementations I've seen), and the
average is probably double that. On the other hand, I tend to
deal with objects more complex than strings---in a lot of cases,
the strings themselves are in objects which use COW (or aren't
copiable). So I really don't know what the best solution is.

> > For some numbers (populating a vector with 8 char long
> > strings via push_back(), running on a Core i7 on Windows):

> > Small string optimization (as I posted, 8-char buffer): 780ms
> > Small string optimization (as I posted, 32-char buffer): 1550ms
> > Dynamic allocation: 15'000ms
> > Thread-safe COW String (Qt QByteArray): 3400ms
> > std::basic_string (Dinkumware, uses small string optimization): 3900ms

> Naturally allocation will be significantly slower than simply
> assigning to a member array. But only using 8 char long
> strings for such a test feels a bit artificial.

It depends on what you're doing. In my case, where I'm working
now, it is artificial. But I've seen applications where most of
the strings were either numerical values (six to eight digits),
or country or currency codes (two or three characters).

This is definitely a case where one size doesn't fit all.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


== 2 of 2 ==
Date: Wed, Jul 29 2009 3:47 am
From: tni


Juha Nieminen wrote:
> tni wrote:
>>> What advantages does a string class with SSO have over one which
>>> always allocates the string dynamically and uses CoW?
>> Copying is much faster for small strings (at least on some important
>> platforms like x86).
>
> I don't see how that would be the case. With a regular CoW string a
> copy entails assigning one pointer and updating one counter at the end
> of that pointer.

Not for a multi-threaded environment.

E.g. for QByteArray, you have code like this (x86 disassembly):

00401BF5 or ecx,0FFFFFFFFh
00401BF8 lock xadd dword ptr [eax],ecx
00401BFC jne 00401C0C

Note the lock prefix. That's quite expensive.

> Copying a string which uses SSO entails a check whether
> the string is small or dynamically allocated, and then (assuming it is
> small) a copy of a member array (which is probably several times larger
> than a pointer) and the size member variable.
>
> I could even believe that with optimal cache behavior and such you
> could even achieve similar speeds, but much faster? I don't see that
> happening.
>
> (And of course if the string was not small, but dynamically allocated,
> the copying will be basically identical except that there will be the
> additional check before copying.)
>
>> For COW, you generally need some form of reference counting with atomic
>> counters.
>
> The STL, at least the implementation in gcc, has never bothered with
> atomicity...

You are quite wrong. GCC 4.4, basic_string.h:

struct _Rep_base
{
size_type _M_length;
size_type _M_capacity;
_Atomic_word _M_refcount;
};

Note the atomic reference counter.

Even for the oldest version of GCC 3 from 2000 (I haven't bothered to
check 2.x), it's atomic:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/bits/basic_string.h?rev=1.1&content-type=text/x-cvsweb-markup

> Naturally allocation will be significantly slower than simply
> assigning to a member array. But only using 8 char long strings for such
> a test feels a bit artificial.

That's going to be highly application specific. I've had use cases like
that.

For 32-char strings:

Small string optimization (as I posted, 32-char buffer): 1830ms
Dynamic allocation: 17'000ms
Thread-safe COW String (Qt QByteArray): 3900ms
std::basic_string (Dinkumware, uses small string optimization): 8400ms

The previous 8-char numbers:

Small string optimization (as I posted, 8-char buffer): 780ms
Small string optimization (as I posted, 32-char buffer): 1550ms
Dynamic allocation: 15'000ms
Thread-safe COW String (Qt QByteArray): 3400ms
std::basic_string (Dinkumware, uses small string optimization): 3900ms

==============================================================================
TOPIC: strcpy vs memcpy
http://groups.google.com/group/comp.lang.c++/t/71a5945deead500c?hl=en
==============================================================================

== 1 of 2 ==
Date: Wed, Jul 29 2009 2:29 am
From: Pallav singh


when we should use strcpy( ) and when memcpy( ) ? is it w.r.t. to
Data Type

Thanks
Pallav


== 2 of 2 ==
Date: Wed, Jul 29 2009 3:54 am
From: Richard Herring


In message
<9e2b264b-3358-4e0d-b5af-57ed060a4c27@x5g2000prf.googlegroups.com>,
Pallav singh <singh.pallav@gmail.com> writes
>when we should use strcpy( ) and when memcpy( ) ?

Oversimplifying, of course:

Should? Never.
Must? When there's no other choice.

If you have a real problem which involves copying, post the code and
someone will be happy to advise.

--
Richard Herring

==============================================================================
TOPIC: static member variable
http://groups.google.com/group/comp.lang.c++/t/e1a69a5a67723783?hl=en
==============================================================================

== 1 of 4 ==
Date: Wed, Jul 29 2009 2:33 am
From: James Kanze


On Jul 28, 8:50 pm, siddhu <siddharth....@gmail.com> wrote:
> A.cpp will be something like.

> A::i=0; // without mentioning the type of i

That's also a legal statement in C++, but it's not a definition,
it's an expression statement. One of the reasons (in C++) that
you have to mention the type is because that's how the compiler
recognizes that the statement is a declaration, and not an
expression. (In the case of C++, it's actually a lot more
complicated, since expressions can also begin with the name of a
type. But that was the case in C.)

> Do we provide the type for compiler's convenience?

One could argue that it is provided for better error checking.
In this case, however, I'm sceptical---I think it's mainly a
result of C++ grammar rules, which derive from those of C. But
regardless of the language, you do need some way to tell the
compiler that what follows is a variable definition, and not
something else. In your example, "int" is about as short as it
gets---there'd be no advantage in replacing it with e.g. "var".
But for complicated types (e.g. something like std::vector<
MyNamespace::MyClass::MyNestedClass >::const_iterator), one
might argue in favor of allowing auto here as well:
auto A::i = ... ;
, since as you say, the compiler knows the type already. On
the other hand, one could argue against it on the grounds of
orthogonality: the compiler doesn't always know the declared
type of the variable, because not all variables have to be
previously declared, and it's perhaps confusing that the actual
type used comes from a previous declaration, if one is present,
or from the initialization expression otherwise. (The current
rule is that it always comes from the initialization
expression.)

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


== 2 of 4 ==
Date: Wed, Jul 29 2009 2:35 am
From: James Kanze


On Jul 28, 11:38 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> Paul Brettschneider wrote:
> > decltype(A::i) A::i = 0;
> > :-P

> I think this would be handier (although I can't say how
> unambiguous or easy to parse it would be):

> auto A::i = 0;

And what about this:
extern long x ;
auto x = 0 ;
What worries me about this suggestion is that depending on
context, the type resulting from auto depends on a previous
declaration or the initialization expression. Which could lead
to confusion.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

== 3 of 4 ==
Date: Wed, Jul 29 2009 2:36 am
From: James Kanze


On Jul 28, 8:02 pm, r...@zedat.fu-berlin.de (Stefan Ram) wrote:
> siddhu <siddharth....@gmail.com> writes:
> >//A.h
> >Is it a redundant information we are giving to the compiler
> >or is there a logical reasoning behind this?

> When A.h is included in other source files, it is not
> redundant, because in other source files, there is no other
> declaration of i.

> When A.h is included in A.cpp, it is not redundant, because
> it helps to find errors that might occur, when the
> redeclaration is not compatible with the first declaration.

I think his proposal was to not have to repeat the type in the
definition in A.cc; the only place the type would be specified
would be in A.hh.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

== 4 of 4 ==
Date: Wed, Jul 29 2009 3:13 am
From: ram@zedat.fu-berlin.de (Stefan Ram)


James Kanze <james.kanze@gmail.com> writes:
>I think his proposal was to not have to repeat the type in the
>definition in A.cc; the only place the type would be specified
>would be in A.hh.

One wants what I call »centralization«, that is, each
information should be stored only at no more than one location
in the world.

But why? So that we only need to do /one/ change, when this
record of information is supposed to change.

So, one wants the datatype »int« to be mentioned only once for
a given variable (in the header file, not in the source file).

But, if this would be possible, would it help to change the
type just once and be done? Most often, not, because usually
many other pieces of code depend on this type and need to be
changed, too.

Repeating the »int« in the source file, also gives some more
readability to this location (the human reader might not
immediatly know the »decltype« of an identifier).

One »modern« solution to the »problem« of changing the
datatype of a declaration only once might be a refactor
function in an IDE that will change the type of an identifier
in all its declarations within a given set of source files.

One solution for people with much leisure: Write your own
module definition language on top of C++. Define a »module« in
this language. Then, your translator will generate a pair of
».h« and ».cpp« files from you module definition file.

A rough attempt to do something like this sometimes is:

int i
#if !INCLUDED
= 0

No comments: