Friday, November 7, 2014

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

comp.lang.c++@googlegroups.com Google Groups
Unsure why you received this message? You previously subscribed to digests from this group, but we haven't been sending them for a while. We fixed that, but if you don't want to get these messages, send an email to comp.lang.c+++unsubscribe@googlegroups.com.
Paul <pepstein5@gmail.com>: Nov 07 03:13PM -0800

A website promoting a book on design patterns has the code below. Presumably the virtual destructor has been incorrectly omitted, but that might be forgiven because it's not really relevant to the main point.
 
However, I am concerned about the code duplication here -- the line v.visit(this) is just repeated verbatim regardless of what member of the Element hierarchy v represents. This doesn't strike me as good design.
 
Any ideas of how to resolve this? (Feel free to suggest ideas that break the Visitor pattern).
 
Thank You,
 
Paul
 
#include <iostream>
#include <string>
using namespace std;
 
// 1. Add an accept(Visitor) method to the "element" hierarchy
class Element
{
public:
virtual void accept(class Visitor &v) = 0;
};
 
class This: public Element
{
public:
/*virtual*/void accept(Visitor &v);
string thiss()
{
return "This";
}
};
 
class That: public Element
{
public:
/*virtual*/void accept(Visitor &v);
string that()
{
return "That";
}
};
 
class TheOther: public Element
{
public:
/*virtual*/void accept(Visitor &v);
string theOther()
{
return "TheOther";
}
};
 
// 2. Create a "visitor" base class w/ a visit() method for every "element" type
class Visitor
{
public:
virtual void visit(This *e) = 0;
virtual void visit(That *e) = 0;
virtual void visit(TheOther *e) = 0;
};
 
/*virtual*/void This::accept(Visitor &v)
{
v.visit(this);
}
 
/*virtual*/void That::accept(Visitor &v)
{
v.visit(this);
}
 
/*virtual*/void TheOther::accept(Visitor &v)
{
v.visit(this);
}
 
// 3. Create a "visitor" derived class for each "operation" to do on "elements"
class UpVisitor: public Visitor
{
/*virtual*/void visit(This *e)
{
cout << "do Up on " + e->thiss() << '\n';
}
/*virtual*/void visit(That *e)
{
cout << "do Up on " + e->that() << '\n';
}
/*virtual*/void visit(TheOther *e)
{
cout << "do Up on " + e->theOther() << '\n';
}
};
 
class DownVisitor: public Visitor
{
/*virtual*/void visit(This *e)
{
cout << "do Down on " + e->thiss() << '\n';
}
/*virtual*/void visit(That *e)
{
cout << "do Down on " + e->that() << '\n';
}
/*virtual*/void visit(TheOther *e)
{
cout << "do Down on " + e->theOther() << '\n';
}
};
 
int main()
{
Element *list[] =
{
new This(), new That(), new TheOther()
};
UpVisitor up; // 4. Client creates
DownVisitor down; // "visitor" objects
for (int i = 0; i < 3; i++)
// and passes each
list[i]->accept(up);
// to accept() calls
for (int i = 0; i < 3; i++)
list[i]->accept(down);
}
DSF <notavalid@address.here>: Nov 06 11:11PM -0500

On Thu, 06 Nov 2014 15:25:18 -0600, Paavo Helde
 
>'Data segment' is not a term which comes up in the standard. Translated
>to the standardese, your question is: do the static data members of a
>class template have internal or external linkage?
 
Understood about the terminology, but your translation is a bit off.
True external linkage would lead to the same identifier declared in
every TU using FString.h, which would normally be a linker error. I
know C++ has a different method of handling this to allow:
const int three = 3
To be placed in a header file in lieu of:
#define three 3
Internal linkage, I believe, would result in one "blank" per TU
using FString.h.
 
What I'm unclear about is if external linkage would be translated
into one single copy of "blank". Note that I don't care how many
"blank"s there are (within reason), I'm just curious as to how the
language handles this situation.
 
>linkage.
 
>3.4.6/5: a [...] static data member [...] has external linkage if the
>name of the class has external linkage.
 
"blank" would have external linkage. So the linker handles the
situation of multiple "blank"s with external linkage.
 
>particular, the compiler can choose to optimize it fully away so there is
>no space taken in any data segment, or to collide them all together so
>there is only a single 'blank' for all instantiations and all TU-s.
 
But shouldn't static have an effect here? The compiler should NOT
be able to optimize it fully away because it is declared static inside
a template class declaration, indicating a desire for one instance,
not internal linkage. I would think this would be a clear indication
that the programmer wants an instance of the variable and is not just
using it as an immediate value. I say "should" because I don't know
this for a fact, it just seems logical.
 
And even if I am wrong about the above, the template class uses a
pointer to "blank" (&blank) which, if I recall correctly, prevents the
compiler from optimizing it away.
 
I have an answer as it pertains to my compiler. I set a breakpoint
where "blank" is used in a program with many TUs using FString.
Regardless of the calling point, "blank" always was at the same
address.
 
DSF
"'Later' is the beginning of what's not to be."
D.S. Fiscus
Paavo Helde <myfirstname@osa.pri.ee>: Nov 06 11:51PM -0600

DSF <notavalid@address.here> wrote in
 
> Understood about the terminology, but your translation is a bit off.
> True external linkage would lead to the same identifier declared in
> every TU using FString.h, which would normally be a linker error.
 
There are special provisions for templates which effectively say these
linker errors must not occur (except for fully-specialized templates,
which are essentially not templates any more).
 
> #define three 3
> Internal linkage, I believe, would result in one "blank" per TU
> using FString.h.
 
This rule is for top-level (namespace scope) const variables, this is not
the case here.
 
> be able to optimize it fully away because it is declared static inside
> a template class declaration, indicating a desire for one instance,
> not internal linkage.
 
Maybe you are right. As it is not of internal linkage, it can be
potentially observed in other TU-s and so cannot be completely optimized
away.
 
> And even if I am wrong about the above, the template class uses a
> pointer to "blank" (&blank) which, if I recall correctly, prevents the
> compiler from optimizing it away.
 
True.
 
> where "blank" is used in a program with many TUs using FString.
> Regardless of the calling point, "blank" always was at the same
> address.
 
That's how it must behave as far as I understand, for the same CH type.
 
I am more interested in about the rules for different template
instantiations. The 'blank' has the same type in all instantiations, so
it is conceivable only one of them is created even if its/their address
is taken. My compiler (MSVC2012) creates exemplars with different
addresses for each template instantiation (different CH) for non-const
'blank', but a single merged object for const 'blank'. I am not sure if
the latter is standard-conforming. Indeed, another compiler (gcc) keeps
them separate in both const and non-const cases.
 
Cheers
Paavo
DSF <notavalid@address.here>: Nov 07 03:04PM -0500

On Thu, 06 Nov 2014 23:51:09 -0600, Paavo Helde
>> using FString.h.
 
>This rule is for top-level (namespace scope) const variables, this is not
>the case here.
 
I understand.
 
>'blank', but a single merged object for const 'blank'. I am not sure if
>the latter is standard-conforming. Indeed, another compiler (gcc) keeps
>them separate in both const and non-const cases.
 
Does MSVC2012 create duplicate "blank"s for each instance even if
they are in the same TU? I would think that would be erroneous if
your 'blank' is declared static. Come to think of it, there should be
only one 'blank' for every instance of the class, even across TUs, as
long as your template class, and therefore 'blank', have external
linkage.
 
I think I understand MS's reasoning here in regard to const. Without
const, 'blank' may be changed per instance (or perhaps per TU,
depending on your answer to the above question regarding static). If
'blank' is always the same type, always initialized to the same value,
and const, then there is no reason to have more than one instance of
'blank' as 'blank' must contain the same value for the duration of the
program.
 
>Cheers
>Paavo
 
Thanks,
DSF
"'Later' is the beginning of what's not to be."
D.S. Fiscus
Paavo Helde <myfirstname@osa.pri.ee>: Nov 07 04:09PM -0600

DSF <notavalid@address.here> wrote in
> only one 'blank' for every instance of the class, even across TUs, as
> long as your template class, and therefore 'blank', have external
> linkage.
 
No, it does not create a separate 'blank' for each instance of the class
(i.e. object). It does create a separate 'blank' for each different
instantiation of the class template if 'blank' is not const (as it should
do).
 
> and const, then there is no reason to have more than one instance of
> 'blank' as 'blank' must contain the same value for the duration of the
> program.
 
If its address is not taken, then I agree with you. But if the address of
the static member is taken, then I think different template
instantiations should have static members with different addresses. After
instantiation, these are actually totally different classes which have no
relation to each other, so why should some static data member of them to
be located at the same address?
 
And of course, with shared libraries and dynamic linking it is pretty
hard to know in advance if some code will take an address of some
variable or not.
 
Cheers
Paavo
DSF <notavalid@address.here>: Nov 07 04:54PM -0500

On Fri, 31 Oct 2014 23:56:34 -0400, "Erdoeban Zsukloff zu Brecher
>met with derision expressed by "Why do you care?", especially on open forum.
>That said, sometimes this very question - "Why do you care?" - does not bear
>derisive emotional load, and is a genuine interest in the subject .
 
That's a problem with most text communication: It doesn't convey
the emotions behind the words. Does
"Why do you care?"
mean "That's not important." or "That's none of your concern."
or does it mean "Is this important to your current work, or are you
going off on an unnecessary tangent?
 
>This email is free from viruses and malware because avast! Antivirus protection is active.
>http://www.avast.com
 
>--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
DSF
"'Later' is the beginning of what's not to be."
D.S. Fiscus
woodbrian77@gmail.com: Nov 06 06:09PM -0800

On Thursday, November 6, 2014 1:18:54 PM UTC-6, Mr Flibble wrote:
 
> A proper fix would be to have "Give()" use an out parameter rather than
> a return value thereby preventing the problem from occurring in the
> first place.
 
One thing I like about the approach that returns a value
is it can be used in an initializer list.
 
 
Brian
Ebenezer Enterprises - "In the L-rd I take refuge" Psalms 11:5
http://webEbenezer.net
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Nov 07 01:54PM

>> first place.
 
> One thing I like about the approach that returns a value
> is it can be used in an initializer list.
 
The only other option is using some kind of lazy evaluation hack; apart
from that I can think of no way to prevent that type of bug reoccurring
(apart from using out parameters of course).
 
/Flibble
woodbrian77@gmail.com: Nov 07 06:56AM -0800

On Friday, November 7, 2014 7:54:31 AM UTC-6, Mr Flibble wrote:
 
> The only other option is using some kind of lazy evaluation hack; apart
> from that I can think of no way to prevent that type of bug reoccurring
> (apart from using out parameters of course).
 
How about defining the order of evaluation as either
left-to-right or right-to-left?
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Nov 07 04:56PM

>> (apart from using out parameters of course).
 
> How about defining the order of evaluation as either
> left-to-right or right-to-left?
 
You mean change C++? Don't be silly.
 
/Flibble
"Öö Tiib" <ootiib@hot.ee>: Nov 07 01:49PM -0800

On Friday, 7 November 2014 15:54:31 UTC+2, Mr Flibble wrote:
 
> The only other option is using some kind of lazy evaluation hack; apart
> from that I can think of no way to prevent that type of bug reoccurring
> (apart from using out parameters of course).
 
The iostream-style chaining of operations is also option. That takes
turning brian's logic from "buf" "giving" things to "stuff" into
"stuff" "taking" things out of "buf". Also chaining free functions
looks ugly so either he has to make the functions members of "buf"
or to overload operators (like iostream does).
Rosario193 <Rosario@invalid.invalid>: Nov 07 10:30AM +0100


>int main (int argc, char* argv[]) {
> char ch;
> ch = argv[argc][0]; // this line gives a seg fault
 
for me argv[argc]==0 is true...
becouse the ones define the language, if i rememeber well,
define that has to be so
 
the 0 in "argv[argc]==0" has size of char*
 
so when you do ch=argv[argc][0]
it is like you do ch=0[0]
that is like you do ch=*0
that can[has to] seg fault [at last here]
 
scott@slp53.sl.home (Scott Lurndal): Nov 07 09:14PM


>for me argv[argc]==0 is true...
>becouse the ones define the language, if i rememeber well,
>define that has to be so
 
The C standard (9989:201x) (5.1.2.2.1) requires that:
 
argv[argc] shall be a null pointer.
 
I wouldn't rely on it, myself.
 
Dereferencing a null pointer is undefined. Which is why
 
 
>>examine the byte that is supposed to be nullptr, and I'm having a
>>tough time of it.
 
>>To my understanding, the expression argv[argc][0] returns a char.
 
Because you are dereferencing a null pointer. The behavior of that
operation is undefined.
 
argv[argc] == NULL
 
scott
DSF <notavalid@address.here>: Nov 07 02:25PM -0500

On Sat, 11 Oct 2014 14:55:45 -0500, Paavo Helde
<myfirstname@osa.pri.ee> wrote:
 
I just ran across this message. Sorry for the late reply.
 
 
>> typedef FString<char> FStringA;
>> typedef FString<wchar_t> FStringW;
 
>Note that on a lot of platforms wchar_t is 32-bit.
 
Yes, I know. The FString class makes a lot of calls to functions
that assume wide == 16-bit. But I doubt any of my code will ever see
the light of day beyond my own projects, so portability is not my
chief concern right now.
 
 
>names are all-capitals. On top of that, having the macro name the same as
>the class name is just confusing as hell. What's wrong with a typedef and
>using different names?
 
I know macros bridge across all namespaces. And, more importantly
to me at this time, bridge across all classes. (Come to think of it,
inside a class is a namespace.)
 
In this case, I believe the very fact that the macro bridges all
boundaries is an asset. After all, the UNICODE definition is most
often used as a program-wide indication of 8-bit or 16-bit characters
in Window$.
 
Out of curiosity (and future use), how could I write a
namespace-aware version of the above?
 
To the best of my knowledge, it is not a rule that macros must be
all caps. On my compiler, the function getchar which is listed as a
Standard function, is a macro. None of the functions implemented as
macros are all upper case. I personally use all upper case for macros
that define an immediate value and use mixed case for macros that
simplify a function call.
 
As to "confusing as hell," actually I thought having the names the
same would be confusing, if it even worked. But it's not. They are
tucked away at the end of FString.h and forgotten about. If I am
writing code dependant on the UNICODE definition, I use FString. If I
need a specific type, such as ANSI (or even UTF-8), I explicitly use
FStringA.
 
>macro any more.
 
>PS. I'm just curious in what way your string class is better than
>std::basic_string?
 
It's not. But writing it has taught me a lot about templates. I've
also written my own array-type templates for the same reason. Most
books and online articles cover only the most basic elements of
templates, leaving me with the thought "Fine! I Understand. But how do
I do this?" Once I started writing my own, I was able to formulate
better questions and thus, search for better information.
 
By the way, I've found - at least for me - that studying the STL to
learn to write templates is, to borrow your phrase "confusing as
hell". :o)
 
>Cheers
>Paavo
 
Thanks for the input,
DSF
"'Later' is the beginning of what's not to be."
D.S. Fiscus
DSF <notavalid@address.here>: Nov 07 02:35PM -0500

On Sat, 11 Oct 2014 17:29:12 -0700 (PDT), "Charles J. Daniels"
 
>> DSF
 
>> "'Later' is the beginning of what's not to be."
 
>> D.S. Fiscus
 
If you include the CH template parameter, I would expect these
functions to only accept other FStrings of similar CH foundation, be
it unicode/wchar_t or ansi/char. Without an explicit parameter, it may
very well accept either type (I'm not 100% certain but fully expect
that is correct), and that is not what you want. Test to see if an
FStringW will accept FStringA arguments -- you don't want that unless
you code with it in mind. My recommendation is to limit the arguments
to similar character base by using the CH parameter explicitly to keep
them common.
 
Thank you for the input.
 
You might want to check the margins in your newsreader. Your reply
showed up as one long line in mine. I had to copy and paste it into
Notepad with Word Wrap on to read it. When I removed the quote
character ">" in this reply, it collapsed to my margins.
 
Thanks again,
 
DSF
"'Later' is the beginning of what's not to be."
D.S. Fiscus
Laurent <laurent.plagne@gmail.com>: Nov 06 11:11PM -0800

Le jeudi 30 octobre 2014 13:31:27 UTC+1, Juha Nieminen a écrit :
> other words, said function just takes one parameter), and all these
> calls basically separated with commas.
 
> --- news://freenews.netfront.net/ - complaints: news@netfront.net ---
 
Thank you very much for your detailed explanation. The last example showing how to apply a given function to all the parameters matches exactly my current need !
I wonder if I can use the result as a variadic argument for another function
anotherFunction(someFunction(parameters)...)
I will try this.
Thank you again !
Laurent
Juha Nieminen <nospam@thanks.invalid>: Nov 07 02:53PM

> I wonder if I can use the result as a variadic argument for another function
> anotherFunction(someFunction(parameters)...)
 
That means that it, roughtly speaking, gets expaned to:
 
anotherFunction(someFunction(param1), someFunction(param2), (etc))
 
In other words, 'anotherFunction' needs to be able to take a variable
number of parameters of the return value type of 'someFunction'.
 
(Note that it is possible to restrict the number of parameters given
to a variadic template, which can sometimes be useful. This happens
by writing a static_assert inside the template where you check that
sizeof...(parameters) is within the limits you want.)
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
Marcel Mueller <news.5.maazl@spamgourmet.org>: Oct 31 02:15AM +0100

With C++11 the standard containers like vector, deque etc. got a new
function emplace to construct new objects in place. Very useful, from my
point of view. I almost do not use anything else anymore.
 
But what about the other direction? How to remove objects with move
semantics? pop_back does not return anything, and there is no new
function which returns an rvalue reference. Did I miss something?
 
 
Marcel
Melzzzzz <mel@zzzzz.com>: Oct 31 01:03AM +0100

On Thu, 30 Oct 2014 13:42:51 -0700 (PDT)
 
> Why does g++ generate this warning?
 
It is useful. clang issues exactly same warning, too.
 
 
--
Manjaro all the way!
http://manjaro.org/
Christopher Pisz <nospam@notanaddress.com>: Oct 30 05:26PM -0500

On 10/30/2014 4:53 PM, jacob navia wrote:
 
> Even if it is 100% LEGAL C++ CODE!
 
> The code has an error. Yes. But it is not necessary nor even justified
> to go on with your "anti C " campaign.
 
(good)C++ programmers don't use #include <stdio.h>, (most)C programmers do.
 
(good) C++ programmers don't usually pass raw pointers to public methods
or global functions, (most) C programmers do
 
(good) C++ programmers certainly would check if the pointer was null
before using it, (most) C programmers rely on foreknowledge and would
say, "Well, we just know the pointer has to be initialized before using
it", that's the way this API works.
 
This was a very good example of how C style code creates unexpected
errors. If he has passed the int by reference or by one of the many C++
constructs to manage pointers, then the error would have never occurred.
 
and you can see by his responses to why he didn't pass it by reference
and why he returns (0) instead of returning 0, that he is a C style
programmer, because he chalks it up to his personal preference and as is
the case all too often with C style code, that personal preference made
the code more error prone.
 
When "my preference" > "maintainability" we have a problem.
Barry Schwarz <schwarzb@dqel.com>: Oct 30 03:39PM -0700

On Thu, 30 Oct 2014 17:32:18 -0500, Christopher Pisz
>business looking at. Then we are dereferencing that memory and doing
>nothing with it.
 
>am I wrong?
 
Yes, you are wrong. It is true that the ++ post-increment operator
increments the value of its operand. However, that incremented value
does not participate in any other operations until a sequence point is
reached. The ++ post-increment operator evaluates to the
un-incremented value of its operand. The incrementing is often
referred to as a side affect.
 
a = 5;
b = a++;
c = ++a;
 
b will be 5. c and a will both be 7.
 
--
Remove del for email
Luca Risolia <luca.risolia@linux-projects.org>: Oct 30 11:45PM +0100

Il 30/10/2014 23:32, Christopher Pisz ha scritto:
> business looking at. Then we are dereferencing that memory and doing
> nothing with it.
 
> am I wrong?
 
Why don't you try?
 
int a[2] = {0, 1};
int* tnX = a;
assert(*tnX++ == 0);
"Erdoeban Zsukloff zu Brecher Zhuang" <no@contact.com>: Nov 04 10:49PM -0500

> could bet that this has been working with %i for many years.
> I just tested with gcc 4.8.2 for OS/2 - works with %i. But with gcc 4.8.2
> Linux (Mint 17) the result is the bitwise not.
 
#include <stdio.h>
int main()
{ int i;
sscanf("0x80000000", "%i", &i);
printf("%x", i);
return 0;
}
 
> binary, octal, hex) from a string. The string does not necessarily end
> after the number. I did not find format specifier that does the job.
 
> Marcel
 
Are these numbers scattered all over the range, or are there a few specific
constants you're dealing with ? Because if latter (say, 0x80000000 shows up
80% of the time ...) , the fastest and arguably easiest way would be to test
for a pre-set (hardcoded ?) string ...
 
 
---
This email is free from viruses and malware because avast! Antivirus protection is active.
http://www.avast.com
 
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
"Öö Tiib" <ootiib@hot.ee>: Nov 07 01:13AM -0800

On Friday, 7 November 2014 04:51:24 UTC+2, Erdoeban Zsukloff zu Brecher Zhuang wrote:
> constants you're dealing with ? Because if latter (say, 0x80000000 shows up
> 80% of the time ...) , the fastest and arguably easiest way would be to test
> for a pre-set (hardcoded ?) string ...
 
Does code written in GPU assembler contain major amount of constants
0x80000000? What you think?
"Öö Tiib" <ootiib@hot.ee>: Nov 06 04:37PM -0800

On Thursday, 6 November 2014 20:09:28 UTC+2, Marcel Mueller wrote:
> ordered by the second key, because they are always added strongly
> monotonically. So I can easily use one of the borders of equal_range to
> get the most recent version.
 
Compiler? You mean you keep all the names from different scopes in
same container and indicate scope with int? It feels upside
down and it can not be efficient. If it is compiler of something like
C++ then that single int can not be sufficient for name lookup.
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: