Saturday, February 18, 2017

Digest for comp.lang.c++@googlegroups.com - 17 updates in 10 topics

"K. Frank" <kfrank29.c@gmail.com>: Feb 18 02:29PM -0800

Hello Group!
 
Why doesn't the line flagged with the error compile?
(I'm compiling as c++ with g++.)
 
void f() {
if (false);
if ((false));
bool b;
if (b = false);
if ((b = false));
if (bool b = false);
if ((bool b = false)); // error: expected primary-expression before 'bool'
}
 
All but the last of the variations compile, but the last
triggers the noted error. What's the language-standard
analysis that explains this?
 
 
Thanks for any ideas.
 
 
K. Frank
Bo Persson <bop@gmb.dk>: Feb 19 12:26AM +0100

On 2017-02-18 23:29, K. Frank wrote:
 
> All but the last of the variations compile, but the last
> triggers the noted error. What's the language-standard
> analysis that explains this?
 
It's a grammar thing.
 
A primary-expression can inclucde a declaration of a variable, but as
soon as you add a '(' it is an '(expression)', which cannot declare
variables.
 
 
 
Bo Persson
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 18 05:21PM

On 18/02/2017 12:49, Rick C. Hodgin wrote:
[religious bullshit snipped (tl;dr)]
 
Mate, kindly:
 
a) take your medication;
b) fuck off.
 
/Flibble
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Feb 18 10:14AM -0800

Mr Flibble wrote:
[... (tl;dr)]
 
The reason why you think negatively about Christianity, about
Jesus Christ, and about me, is because you have not examined the
content with a true, scrutinizing approach. You have only given
it a cursory glance, and it was from within that small sample that
you were able to conclude "wrong" falsely. A closer scrutiny, with
more proper examination, would remove the things which make
it outwardly look false.
 
If you continue on as you are, your gravestone could read:
 
"Why was Leigh Johnston cast into Hell? One
reason: He thought God's message for His
life was too long, so he didn't read it. And it
was that barrier he imposed which kept him
from coming to know God, and being saved."
 
There are no barriers between us and Christ except for those we
erect ourselves.
 
Thank you,
Rick C. Hodgin
"Christopher J. Pisz" <cpisz@austin.rr.com>: Feb 18 04:48PM -0600

On 2/18/2017 12:14 PM, Rick C. Hodgin wrote:
> erect ourselves.
 
> Thank you,
> Rick C. Hodgin
 
I am Christian and I think negatively about you.
 
You are annoying, you are a pest, and worst of all you think you are
actually doing a good thing. If anything you are driving people away
from Christianity.
 
Can you show me the story in the Bible where Jesus goes to preach to
someone and they tell him to fuck off, so he decides to knock on their
door every day for the next 10 years and repeat himself?
 
I've read the Bible some 3 times from front to back and I haven't seen
that story...
"Öö Tiib" <ootiib@hot.ee>: Feb 18 11:40AM -0800

On Saturday, 18 February 2017 13:06:55 UTC+2, JiiPee wrote:
> which pattern it is. Surely a simple question..
 
> Can somebody help me please, what pattern is this when you can add a
> different behaviour by pointer member variable:
 
snip
 
 
> void main()
 
That is called "flame bait" pattern. Posting code with "void main"
in it gets flames in both comp.lang.c and comp.lang.c++ and so livens up
discussions there.
 
> car1.m_drivingStyle = new DriveErratically();
> car1.drive();
> car1.m_drivingStyle = new DriveNormally();
 
That is called "memory leak" pattern. It helps the industry to sell more
and bigger RAM to customer computers.
 
JiiPee <no@notvalid.com>: Feb 18 10:38PM

On 18/02/2017 19:40, Öö Tiib wrote:
> That is called "memory leak" pattern. It helps the industry to sell more
> and bigger RAM to customer computers.
 
 
heh, but can you also now asnwer the question itself???
Vir Campestris <vir.campestris@invalid.invalid>: Feb 18 09:47PM

On 18/02/2017 02:54, Alf P. Steinbach wrote:
 
> were executed in parallel, without `a` and `b` being designed for
> parallelism, e.g. trying to update the same variable.
 
> Explicit is good, implicit is bad. In general. ;-)
 
We have exactly the same problem with a call like
x(a(), b()) - the order of evaluation there is undefined. Every system
I've ever used does it one way. Or the other. But never both. Why should
the order of evaluation in the explicit calls in your example be
defined? (The effects of reordering the operator<< calls would however
be bad)
> the `<iostream>` header. It is now, as of C++11 and later.
 
> So, is the presumed original intent of /unspecified/ behavior
> incompatible with your envisioned possible parallelism?
 
in i = v[i++] we have two things going on - the assign and the
increment. I see no reason why the language should define which happens
first.
 
I'd like a compiler that would tell me not to be so silly.
 
Andy
--
I'm doing too much C these days :(
Tim Rentsch <txr@alumni.caltech.edu>: Feb 18 08:58AM -0800

Chris Vine writes:
 
>>>> compilers support it. It is usage that std::variant does
>>>> not allow. Type-punning can be achieved with 'reinterpret_cast'
>>>> or with 'memcpy' so union is also not needed for it.
 
[...]
 
> standard which says so explicitly: it seems to be taken to be implied
> by the statement in the standard that "at most one of the non-static
> data members of an object of union type can be active at any time".
 
After seeing this comment I looked into this question (again), a
little more deeply this time. I am now of the opinion that
accessing a member other than the active member is defined
behavior, and not undefined behavior, subject of course to the
usual caveats about relative sizes, depending on representations,
etc. My reasoning is as follows (referencing C++14 of n4296).
 
In section 5.20 paragraph 2, defining a core constant expression,
one of the exclusions listed is (2.5)
 
an operation that would have undefined behavior
 
A little further on, in (2.8), there is another exclusion
 
an lvalue-to-rvalue conversion [...] that refers to a
non-active member of a union [...]
 
There would be no reason to list the second case if it were
already undefined behavior. I believe it is generally accepted
that writing in the C++ standard tries to avoid this sort of
redundancy. Hence it follows that (most likely) the authors
consider such accesses defined behavior rather than undefined
behavior (as before, subject to the usual caveats).
 
What do y'all think?
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 18 09:19PM +0100

On 18.02.2017 17:58, Tim Rentsch wrote:
> consider such accesses defined behavior rather than undefined
> behavior (as before, subject to the usual caveats).
 
> What do y'all think?
 
There is a paragraph with an intended-to-be-exhaustive bullet point list
of supported reinterpretations of bitpatterns. The gcc folks call it
/the strict aliasing rule/ of C++ and are pretty zealot-like about it
because of the silly behavior of that compiler: that one is supposed to
introduce inefficiency via `memcpy`, ideally two calls of `memcpy` per
reinterpretation, and hope to have that inefficiency optimized away by
the compiler, just to avoid its warnings and possibly
royally-screw-things-up pseudo-optimizations, where otherwise one would
have two pointers to different types really pointing to the same object,
i.e. aliased pointers. The standard doesn't call it strict aliasing so
I'm not sure how to search for it, and I always forget where it is.
 
Anyway,
 
• The list is not really exhaustive, it has at least one one-way
reinterpretation.
 
• The reinterpretations supported is where some common part of the
bitpattern really means the same in the two interpretations, e.g. signed
versus unsigned interpretation for non-negative integers.
 
• The reinterpretations of interest via type punning in e.g. a union,
are generally those not in the strict aliasing rule bullet list.
 
What you quoted seems to be about any reinterpretation at all not being
permitted in a constant expression.
 
 
Cheers & hth.,
 
- Alf
"Öö Tiib" <ootiib@hot.ee>: Feb 18 11:12AM -0800

On Friday, 17 February 2017 22:12:22 UTC+2, bitrex wrote:
> used as a unit test to ensure a resource-managing class, which has all
> of the "Rule of Five" constructors and assignment operators explicitly
> defined is working properly?
 
 
No, but for most types of resources managed (like thread, file, hardware
device, network socket and the like) copy constructor and copy assignment
do not make any sense. Therefore those two short tests are usually handy:
 
ststic_assert(!std::is_copy_constructible<Foo>::value
, "Foo should not be copy constructible");
 
ststic_assert(!std::is_copy_assignable<Foo>::value
, "Foo should not be copy assignable");
 
If to generalize, then it makes sense to test such type traits as
first thing for any class.
Tim Rentsch <txr@alumni.caltech.edu>: Feb 18 08:36AM -0800

> to refer to selectable objects, most often it requires to be allowed
> to refer to no object as well: typically such a variable is meant to
> address an object in a set, and typically sets can be empty.
 
No doubt that property is often true, but certainly it isn't
always true. A couple of counterexamples immediately come to
mind: one, a circular list (doubly linked) with a dummy node
pointing to the head and tail; and two, a 2-3 tree with internal
nodes (holding 1 value and 2 subtrees, or 2 values and 3
subtrees) and leaf nodes (holding 1 value or 2 values, and no
subtrees). Any external pointers to these structures are most
likely nullable, but the internal pointers should never be null
(and they do need to change as the structures grow and shrink).
 
It would be interesting to try a language experiment where
pointer types normally are not nullable, and a pointer type that
needs to be nullable would require writing, eg,
 
int *nullable p;
 
(I may have read this suggestion somewhere else, and if I could
remember if and where I would gladly give credit. I make no
claim for originality here.)
Manfred <noname@invalid.add>: Feb 18 07:49PM +0100

On 2/18/2017 5:36 PM, Tim Rentsch wrote:
> No doubt that property is often true, but certainly it isn't
> always true.
Agreed.
My point was about common use, specific cases are always possible.
The question is if the language should provide explicit facilities for
such specific cases.
Personally I think that added features always carry some cost, so they
should be widely applicable to be justified.
I always liked the essential nature of C++ - I mean being based on a
limited number of powerful and solid concepts - as opposed to other
languages that are more feature-richness oriented, but quite dispersed
into a plethora of specific use cases.
Paavo Helde <myfirstname@osa.pri.ee>: Feb 18 08:33PM +0200

On 18.02.2017 9:27, kushal bhattacharya wrote:
> To put it in other words i want to use c++ as backend for processing tasks from the client end just as php or any other server side scripting language does
 
This would be HTTP, not HTML. Maybe you wanted to say that your
responses would mostly be in HTML?
 
For an HTTP server one can use Boost.asio, it's a great library. The
library itself covers only sockets and TCP, but there are examples
featuring a simple HTTP server which you can build on.
 
For producing HTML the simplest approach is to use std::string +=
operation and a couple of utility functions for quoting the content
properly. It is actually very easy to produce HTML, with a bit of
discipline this can be even somewhat readable.
 
Alternatively, you can build some XML tree in memory by using one of the
various XML libraries, and then dump it as an XML+HTML response to the
client. This method is more scalable than string concatenation (or PHP,
for that matter). A further development along those lines would involve
some XML templates in disk files which would be read in and parsed into
XML trees in memory, then adjusted as needed for a concrete response by
using the XML library, then dumped out to the client as before.
 
The simplest such XML library for C++ is TinyXML, it has the great
benefit that one can actually read its code and understand what it's
doing. A drawback is that it allocates each XML node separately, which
may be pretty slow for large XML-s (but this won't probably matter for
any HTML page meant for human consumption).
 
HTH
Paavo
"K. Frank" <kfrank29.c@gmail.com>: Feb 18 08:50AM -0800

Hi Chris!
 
On Saturday, February 18, 2017 at 5:51:41 AM UTC-5, Chris Vine wrote:
> As regards your non-templated RecursiveClass, your use of
> std::unique_ptr looks OK. If your compiler supports C++17, as an
> alternative you could try std::optional, which I have never used.
 
Could you illustrate what you have in mind for std::optional
with some sample code? I'm trying to see how I would make it
work.
 
I can't (I believe -- please correct me if I'm wrong.) have
 
std::optional<RecursiveClass> orc_;
 
as a member of RecursiveClass.
 
So it would seem I would need a pointer-to-optional
or an optional pointer, i.e.,
 
std::optional<RecursiveClass>* porc_;
std::optional<RecursiveClass*> oprc_;
 
as my class member.
 
But I don't see what this buys me -- the optional could
be empty or the pointer could be null (or both), but this
doesn't seem to be a simplification.
 
> ...
> Chris
 
 
Thanks for your thoughts.
 
 
K. Frank
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Feb 18 05:55PM

On Sat, 18 Feb 2017 08:50:31 -0800 (PST)
 
> I can't (I believe -- please correct me if I'm wrong.) have
 
> std::optional<RecursiveClass> orc_;
 
> as a member of RecursiveClass.
 
Can't you? As I say I have never used it,.
 
If you can't, the problem is probably that RecursiveClass is not fully
defined at the point you declare the optional of RecursiveClass
member. This is not an issue with unique_ptr but was with auto_ptr,
and maybe is with optional. Dunno. If you are just playing around with
primitive data types for ideas (which is a great thing to do) perhaps
try another language such as python or my preference for prototyping
ideas, namely scheme.
Tim Rentsch <txr@alumni.caltech.edu>: Feb 18 09:46AM -0800

>> good in the tests I ran).
 
> I never meant to express doubt that you *could* implement a pow()
> function as a constexpr.
 
Right. I never thought otherwise. If anything your earlier
comment suggests you think it could be done, and that is what
prompted my investigation.
 
> somewhere near an ULP - and that flatly rules out any simple
> implementation that does a simple reduction of pow(x,y) to
> exp(y*log(x)) *),
 
Yes, I tried that simple idea later, and it definitely does worse
in the accuracy department, even for the "softball" test cases
I tried.
 
> and handling all the special cases**,
 
I made no attempt to handle those, just "normal values".
 
> would
> doubtless make for some pretty ugly code given the restrictions in
> constexpr function
 
It's not clear to me it would be all that bad, not counting
things like NaNs and maybe values near infinity. Of course
anything involving setting errno is right out.
 
> (although a convention implementation is pretty
> ugly as well, and even so, several hundred lines of code, when you
> count the required support functions).
 
Oh yes. My aims were more modest, to produce fairly high
accuracy for non-pathological argument values. Obviously
you have more experience with these sorts of functions
than I do.
 
> was in Scott's example that I commented on). But it's not at all
> clear to me that this is standard behavior, or something that can be
> counted on.
 
My reading of the C++ standard is that what gcc does is not
required, and so of course cannot be counted on. In fact it
looks like trying to use pow() to initialize a constexpr requires
a diagnostic. The C standard has an escape hatch for different
forms of constant expressions that allow implementations some
freedom to accept extensions to the required set of expressions.
AFAIK C++ does not have a similar rule, but of course I may
have missed something.
 
 
> only do that after scaling both operands to be fairly near the base of
> convenient log and exp functions*** (which will make the result near
> 1.0). You factor the exponents back in after.
 
Yes, that is more or less what I did.
 
> **Most of the various combinations of signs, infinities, NaNs and
> zeros for the two operands end up needing specific handling.
 
Operands being zero is easy to handle - just a couple more cases
in the ?: cascade.
 
For signs, what I did was toss out x**y when x is negative (ie
give a return value of 0), and return 1/x**-y when y is negative.
 
I completely ignored infinities and NaNs. I think infinities
would not be too bad, although cases near the edge might give
bad results. I haven't thought about how to deal with NaNs,
although maybe that isn't too bad either, assuming there is
a constexpr-acceptable way of detecting them.
 
> ***There are various tradeoffs as to the exact range, and it's often
> easiest to split the exponent and mantissa directly from the FP
> format, thus leading to base 2 log/exp.
 
Sadly there is (AFAICT) no way to do that in a way that is
allowed in a constexpr context, at least not directly.
 
Also, a potentially more significant problem - for floating
point, the range and precision at compile time may be different
than what they would be at run time. In practice that might not
be a big deal, but it is something that should be checked.
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: