Tuesday, June 27, 2017

Digest for comp.lang.c++@googlegroups.com - 16 updates in 5 topics

woodbrian77@gmail.com: Jun 27 11:32AM -0700

Shalom
 
In an edit to this post:
 
https://codereview.stackexchange.com/questions/166573/messaging-and-serialization-library
 
, I added links to both versions of the code. Would someone take a look and
let me know what they think?
 
 
Brian
Ebenezer Enterprises - Enjoying programming again.
http://webEbenezer.net
"Öö Tiib" <ootiib@hot.ee>: Jun 27 01:27PM -0700


> https://codereview.stackexchange.com/questions/166573/messaging-and-serialization-library
 
> , I added links to both versions of the code. Would someone take a look and
> let me know what they think?
 
You want code review?
 
From afar looks fine. Closer look reveals too lot of function overloads
named "Marshal" for my taste.
 
Correctness I can't evaluate without knowing requirements to your code.
 
I also do not have actual data to profile your code. Everything being
named "Marshal" would likely make profiling more annoying than usual.
 
What else you would like to know?
woodbrian77@gmail.com: Jun 27 02:43PM -0700

On Tuesday, June 27, 2017 at 3:27:53 PM UTC-5, Öö Tiib wrote:
 
> Correctness I can't evaluate without knowing requirements to your code.
 
> I also do not have actual data to profile your code. Everything being
> named "Marshal" would likely make profiling more annoying than usual.
 
In the original version there are six functions called "Marshal".
I think this is a tame use of overloading.
 
> What else you would like to know?
 
I'm not sure whether to stick with the version that's more
verbose, but that compilers tolerate better, or to switch to
the version that uses variadics.
 
From a code generation perspective, I'd like to use the variadics
version as it's easier to generate since it's less verbose. But if
compilers aren't ready for it, it may be pushing things too much.
 
 
Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net
"Öö Tiib" <ootiib@hot.ee>: Jun 27 03:11PM -0700


> From a code generation perspective, I'd like to use the variadics
> version as it's easier to generate since it's less verbose. But if
> compilers aren't ready for it, it may be pushing things too much.
 
When you are not sure what is better then it can be that neither is
better. For example it can be different per project what is better.
On such cases it may make sense to add optional choice.
scott.a.mayo@gmail.com: Jun 27 09:05AM -0700

I'm checking to see if my understanding of C++ is correct. I've run into problems compiling code under g++ and I'm trying to decide if the problem is mine or g++'s. This wasn't supposed to be complicated...
 
In a header, I have a templated class as a parent class. Relevant excerpts:
 
template<int Size_>
class Buffer {
public:
.....
bool overflowed_; //public
....};
 
//And then I want to base off it with:
 
template<int Size_>
class OutputBuffer : public Buffer<Size_>
{
public:
....
 
OutputBuffer() : Buffer<Size_>() { }
....
void doSomething() { if (overflowed_) {....} } //problems!
};
 
This looks straightforward to me. But for g++ at least, overflowed_, and every other reference to any function or data in Buffer, apparently needs to be qualified with Buffer<Size_>::. This seems especially odd for overflowed_, which doesn't participate in the parameterization of the parent's template. But that shouldn't matter. It's a parent class with public members and it should not matter that it's also templated.
 
Note the compile isn't failing on an instantiation. It fails as soon as the compiler parses the header, before any instantiation is attempted.
 
This makes no sense to me. OutputBuffer is based on a type, and the type is specified by the parent class syntax " : public Buffer<Size_>". When the time comes to instantiate, that parent class will have a definitive definition, but even before that, it seems to be that C++ specifies that the compiler has enough visibility into the subclass to know exactly what I'm referring to. The parent class should be "specified enough" at that point.
 
Other compilers have accepted this, so now I'm trying to determine if this is my problem or g++'s. I can work around it by adding Buffer<Size_>:: everywhere, but that's not how subclassing is supposed to work. (Note I can't avoid g++ - eventually this code is going to a platform where it's likely g++ or nothing.)
 
Insight into why C++ doesn't promise what I want, is welcome. This has messed with my understanding of how templates work.
Paavo Helde <myfirstname@osa.pri.ee>: Jun 27 08:15PM +0300

> void doSomething() { if (overflowed_) {....} } //problems!
> };
 
> This looks straightforward to me. But for g++ at least, overflowed_, and every other reference to any function or data in Buffer, apparently needs to be qualified with Buffer<Size_>::. This seems especially odd for overflowed_, which doesn't participate in the parameterization of the parent's template. But that shouldn't matter. It's a parent class with public members and it should not matter that it's also templated.
 
The idiomatic way to fix this is:
 
void doSomething() { if (this->overflowed_) {....} }
 
See
 
https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members
 
In short, there is no problem with gcc here, but there is a problem with
either your code or possibly with the C++ standard itself if the FAQ
needs to contain such usage warnings as "This might hurt your head!"
"Öö Tiib" <ootiib@hot.ee>: Jun 27 10:47AM -0700

On Tuesday, 27 June 2017 20:15:29 UTC+3, Paavo Helde wrote:
 
> > This looks straightforward to me. But for g++ at least, overflowed_, and every other reference to any function or data in Buffer, apparently needs to be qualified with Buffer<Size_>::. This seems especially odd for overflowed_, which doesn't participate in the parameterization of the parent's template. But that shouldn't matter. It's a parent class with public members and it should not matter that it's also templated.
 
> The idiomatic way to fix this is:
 
> void doSomething() { if (this->overflowed_) {....} }
 
Other way to fix this is to bring the member into scope:
 
using Buffer<Size_>::overflowed_;
 
void doSomething() { if (overflowed_) {....} }
 
> In short, there is no problem with gcc here, but there is a problem with
> either your code or possibly with the C++ standard itself if the FAQ
> needs to contain such usage warnings as "This might hurt your head!"
 
Simpler is just to live with yet another gotcha that
standard requires name overflowed_ to be looked-up in a
base classes, but not in dependent templates of base classes and
to hope that it makes life easier for compiler-makers somehow.
scott.a.mayo@gmail.com: Jun 27 10:51AM -0700

On Tuesday, June 27, 2017 at 1:15:29 PM UTC-4, Paavo Helde wrote:
...
 
> In short, there is no problem with gcc here, but there is a problem with
> either your code or possibly with the C++ standard itself if the FAQ
> needs to contain such usage warnings as "This might hurt your head!"
 
Wow. Yes it worked. I've never come across a situation where this-> was required anywhere. Live and learn, thanks.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 27 08:02PM +0200

> parameterization of the parent's template. But that shouldn't matter.
> It's a parent class with public members and it should not matter that
> it's also templated.
 
 
It matters because the `Buffer` class can be specialized for some
template parameter values, and those specialization will not necessarily
have the `overflowed_` member, or whatever.
 
We say that these expressions /depend/ on the template parameters.
 
A good way to deal with it is to add
 
using Base = Buffer<Size_>;
using Base::overflowed_;
 
Or you can qualify each usage, which is at odds with the principle of
not repeating yourself needlessly.
 
Visual C++ is more lenient because it follows the pre-standard single
phase template parsing rules (disclaimer: I no longer remember the
details of this, I'd have to look it up). I.e. g++ is more conforming
and hence, IMO., more impractical. For I can't remember any single
occasion where this required nonsense verbosity has saved my code from
being incompatible with a nasty specialization of a base class template.
 
 
 
 
> [snip]
 
Cheers & hth.,
 
- Alf
scott@slp53.sl.home (Scott Lurndal): Jun 27 06:08PM

>> either your code or possibly with the C++ standard itself if the FAQ
>> needs to contain such usage warnings as "This might hurt your head!"
 
>Wow. Yes it worked. I've never come across a situation where this-> was required anywhere. Live and learn, thanks.
 
Another place where this-> is required is with member function pointers:
 
e.g.
 
bool (c_processor::*op_insn)(struct _op *);
 
...
 
// Process the instruction
failed = (this->*opp->op_insn)(opp);
legalize+jeeves@mail.xmission.com (Richard): Jun 27 07:18PM

[Please do not mail me a copy of your followup]
 
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> spake the secret code
> using Base::overflowed_;
 
>Or you can qualify each usage, which is at odds with the principle of
>not repeating yourself needlessly.
 
I like this as the minimal change needed to resolve the problem. Can
we do better?
 
What if we move everything that isn't dependent on the template
parameters into a separate base class? This would be a base class
of Buffer<N>:
 
class BufferBase
{
public:
bool overflowed_;
// ...
};
 
template <int Size_>
class Buffer : public BufferBase
{
// ...
};
 
I like this better because it disambiguates the references to
overflowed_ without any using statements in derived classes. It also
clearly separates everything that depends on template parameters from
everything that doesn't which I think makes for a cleaner design.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
legalize+jeeves@mail.xmission.com (Richard): Jun 27 07:18PM

[Please do not mail me a copy of your followup]
 
scott.a.mayo@gmail.com spake the secret code
 
>Wow. Yes it worked. I've never come across a situation where this-> was
>required anywhere. Live and learn, thanks.
 
It isn't required, it is simply one way (of several) to resolve the
ambiguity.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
"Öö Tiib" <ootiib@hot.ee>: Jun 26 11:28PM -0700

On Tuesday, 27 June 2017 00:36:09 UTC+3, Real Troll wrote:
 
> Either you meant: gullible
> or you meant: quibble
 
> Which is it Andy?
 
It is just a play with words. Behaving immature and silly may amuse
but does not unfortunately bring childhood back.
scott.a.mayo@gmail.com: Jun 27 09:17AM -0700

On Monday, June 12, 2017 at 4:59:10 PM UTC-4, gwowen wrote:
> CancellableTimer IS A Timer, so it'd be nice if I could extend Timer in
> this way.
 
> What am I missing?
 
Ignoring all the discussion of LSP this and quibble that, you've already worked out that the destructor in the base class runs regardless. What you're missing is that subclasses generally restrict behaviour, they don't extend it. (That's an exaggeration, but it holds in this case.) Your base class should be CancellableTimer; and if you want a Timer that can't be accidentally cancelled (which you reasonably might), make a subclass that hides the cancellation mechanism. Virtual functions will help.
ram@zedat.fu-berlin.de (Stefan Ram): Jun 27 04:15PM

>overflowed_, and every other reference to any function or
>data in Buffer, apparently needs to be qualified with
>Buffer<Size_>::
 
struct board_type : public ::std::vector< position_type >
{
using ::std::vector< position_type >::vector;
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jun 27 11:19AM

On Mon, 2017-06-12, Adam Badura wrote:
>> interface, it doesn't matter at all to a caller, and so the C++ rules
>> make the following two declarations exactly equivalent, denoting the
>> same function, with the same function type:
...
> (declaration split from definition) you skip the const on
> declaration and have it on definition only? Or for the consistency
> you have it always?
 
"A foolish consistency is the hobgoblin of little minds."
I prefer to have the const only where it carries meaning:
 
void foo(int n);
void foo(const int n) { ... }
 
I think that's how most people do it.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
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: