Friday, September 21, 2018

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

Rosario19 <Ros@invalid.invalid>: Sep 21 12:41PM +0200

On Wed, 19 Sep 2018 11:01:45 -0400, "Rick C. Hodgin" wrote:
 
 
> if (a < b < c < d < e)
> prinf("b is (a, c)\nc is (b, d)\nd is (c, e)\n");
 
>Et cetera... Each evaluated left-to-right.
 
if your target is the "more short" the answer would be (if the
language is free, free of use) APL or some other language the people
in codegolf site use
Siri Cruise <chine.bleu@yahoo.com>: Sep 21 04:02AM -0700

> >Can anyone think of a reason why this type of operation shouldn't
> >be a valid syntax in a (C/C++)-like lanuage, added to that new
> >language with these features:
 
Proposed: an extension of the if statement:
 
if (arithmetic-expression) negative-label, zero-label, positive-label
 
which is equivalent to
 
typeof(arithmetic-expression) T' = (arithmetic-expression);
if (T'<0) goto negative-label;
if (T'=0) goto zero-label;
if (T'>0) goto positive-label;
 
This has the obvious extension

if (exp, exp)
neg-neg-label, neg-zero-label, neg-pos-label,
zero-neg-label, zero-zero-label, zero-pos-label,
pos-neg-label, pos-zero-label, pos-pos-label
 
 
(The more things change, the more they stay the same.)
 
--
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted. @
'I desire mercy, not sacrifice.' /|\
An almond doesn't lactate. This post / \
Yet another supercilious snowflake for justice. insults Islam. Mohammed
David Brown <david.brown@hesbynett.no>: Sep 21 01:19PM +0200

On 21/09/18 13:02, Siri Cruise wrote:
> zero-neg-label, zero-zero-label, zero-pos-label,
> pos-neg-label, pos-zero-label, pos-pos-label
 
> (The more things change, the more they stay the same.)
 
You forgot the smiley. Either this is a joke and needs a happy smiley,
or it is /seriously/ bad and needs a very unhappy smiley.
bitrex <user@example.net>: Sep 21 10:19AM -0400

On 09/20/2018 02:21 AM, David Brown wrote:
> itself is ambiguous.  Yes, I can appreciate that.  There is nothing for
> it but to learn the way C interprets this type of expression - and then,
> like all sane C programmers, avoid writing it.
 
I've been writing C/C++ off and on since ALL THE WAY BACK in the late
1990s and I can't say it ever occurred to me to write a test like if ( a
< b < c ) I'd probably just write (a < b && b < c) by force of habit.
the former is very high-school math-y vs. Boolean logic.
 
with modern C++ I find myself using the "regular" C constructs less and
less and start seeing stuff like multi-way comparisons, nested for
loops, switch statements etc. as possibly more indicative of bad design
then wishing for new operators. I can't think immediately off the top of
my head of a situation where I'd need a four or five way comparison but
now that I have said that it will happen early next week sometime.
 
 
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Sep 21 10:35AM -0400

On 9/21/2018 10:19 AM, bitrex wrote:
> with modern C++ I find myself using the "regular" C constructs less and less
 
One of CAlive's goals is to bring some of C++'s better features to
C, but to not bring in the whole gambit.
 
My goal is to make CAlive be C-like programming with some basic C++
extensions to make syntax easier, and to offer encapsulation.
 
I prefer:
 
object->function(...);
 
Over:
 
function(object, ...)
 
Though in CAlive, whether it's a pointer to an object, or an object
directly, you can use the dot syntax:
 
object.function(...);
 
--
Rick C. Hodgin
Bart <bc@freeuk.com>: Sep 21 03:57PM +0100

On 21/09/2018 15:19, bitrex wrote:
 
 
> with modern C++ I find myself using the "regular" C constructs less and
> less and start seeing stuff like multi-way comparisons, nested for
> loops, switch statements etc. as possibly more indicative of bad design
 
I'd think the same when I see a lack of them.
 
(What would the alternative to nested for-loops be I wonder? Or switch
statements? Or multi-way comparisons, whatever you mean by that. Are we
still allowed 'if' or is that also bad design?
 
I'd be interested in seeing what your code looks like when most control
flow statement are eliminated. I'd imagine it would have either have a
functional look, or perhaps it's just full of C++-ese.)
 
> then wishing for new operators. I can't think immediately off the top of
> my head of a situation where I'd need a four or five way comparison but
> now that I have said that it will happen early next week sometime.
 
Here's one actual example of mine (syntax not from C or C++, so "="
means "=="), which is a 4-way compare:
 
if hd.hsample[2] = hd.vsample[2] = hd.hsample[3] = hd.vsample[3] ...
 
A simpler one:
 
if xt = yt = treal ...
 
Surely everyone at some point must have needed to write the equivalent of:
 
if 'A' <= c <= 'Z' ...
 
(Although I would now write that particular form, for integer values, as:
 
if c in 'A'..'Z' ...)
 
 
These look like no-brainers to me. What objections could anyone possibly
have, other than their favourite language doesn't have such constructs?
 
--
bart
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Sep 21 11:17AM -0400

On 9/21/2018 10:57 AM, Bart wrote:
>  if c in 'A'..'Z' ...)
 
> These look like no-brainers to me. What objections could anyone possibly
> have, other than their favourite language doesn't have such constructs?
 
I can think of three off the top of my head:
 
if (xt = yt = treal) ...
if ('A' <= c <= 'Z') ...
if (c in 'A'..'Z') ... // I like this one
 
In CAlive, I use this:
 
#define between(v,l,h) (c >= l && c <= h)
if (between(c, 'A', 'Z')) ...
 
It would be nice to have:
 
if ('A' < c < 'Z') ...
 
Though I would like this too, and may add it:
 
if (c in {'A'..'Z', '0'..'9', 'a'..'z'}) ...
 
And simplified:
 
if (c in {a_z, 0_9, a_z}) ...
 
We'll see.
 
--
Rick C. Hodgin
ram@zedat.fu-berlin.de (Stefan Ram): Sep 20 10:21PM

I suspect that the size of »int« (and of »long« and other types)
is implementation-defined.
 
But does the standard say so explicitly?
 
I look at n4762 6.7.1 Fundamental types [basic.fundamental] p2:
»Plain ints have the natural size suggested by the
architecture of the execution environment; the other
signed integer types are provided to meet special needs.«.
 
Sure, this is all fine and well. But I was hoping for a
sentence like: »The range of the values of the type int
is implementation-defined.«
 
The "C standard" N2176 says in 5.2.4.2.1 Sizes of integer
types <limits.h> about values like »INT_MIN«:
 
|Their implementation-defined values shall be equal or greater
|in magnitude (absolute value) to those shown, with the same sign.
 
So, there it is! "implementation-defined". But in the C norm.
 
When C++ n4762 says,
 
|16.3.1 General [support.limits.general]
|The headers <limits> (16.3.2), <climits> (16.3.5), and
|<cfloat> (16.3.6) supply characteristics of implementation-
|dependent arithmetic types (6.7.1).
 
, maybe it wants to inherit this specification
("implementation-defined") from C?
 
So does this suffice? Can we now say that
INT_MIN is implementation-defined in C++?
 
And note yet another term as quoted above:
"implementation-dependent"! Here "-dependent"
might not be defined before but just have its common
English meaning. But it does have an index entry:
"implementation-dependent, 370, 452, 1181, 1191".
ram@zedat.fu-berlin.de (Stefan Ram): Sep 21 02:45AM

>However, that does not mean that it's required to document the sizes of
>those types.
 
In the meantime, for C++, I also found this:
 
n4762 4.1.1 p2:
 
|Certain aspects and operations of the abstract
|machine are described in this document as implementation-
|defined (for example, sizeof(int)).
 
Because of the interaction between a line break between
"implementation-" and "defined" (quoted above) and the
system used to search n4762 for strings, the above sentence
was not found when I searched for "implementation-defined".
So, I missed this paragraph!
 
This seems to say that »sizeof(int)« is implementation-
defined. - While I am not totally sure about whether a
text between "(for example," and ")" (nested) is normative.
ram@zedat.fu-berlin.de (Stefan Ram): Sep 21 02:57AM

>However, that does not mean that it's required to document the sizes of
>those types.
 
One might interpret the behavior of »sizeof(int)« to
/be/ documentation supplied by and implementation.
ram@zedat.fu-berlin.de (Stefan Ram): Sep 21 03:02AM

I asked this a year ago or so. But, IIRC, the answers
were not clear to me.
 
So, in
 
n4762 7.6.7 Shift operators [expr.shift]
 
I now can clearly read:
 
|The expression E1 is sequenced before the expression E2.
 
referring to expressions like »E1 << E2« and »E1 >> E2«.
 
Therefore
 
::std::cout << ++i << ++i << '\n';
 
now is not undefined behavior anymore.
 
Please contradict me if you think this is wrong.
ram@zedat.fu-berlin.de (Stefan Ram): Sep 21 03:15PM

>Therefore
>::std::cout << ++i << ++i << '\n';
>now is not undefined behavior anymore.
 
Someone in this newsgroup wrote that the sequencing rules
for the operator "<<" do not apply, when it is executed by a
user-defined function.
 
The above should be similar to
 
operator <<
( operator <<
( operator << ( ::std::cout, ++i ), ++i ), '\n' );
 
Also, a recent gcc still issues a warning
 
warning: operation on 'i' may be undefined [-Wsequence-point]
::std::cout << ++i << ++i << '\n';
 
On the other hand:
 
n4762 11.3.1.2 "Operators in expressions" p2 says:
 
|a user-defined operator function might be declared that
|implements this operator
...
|the operator notation is
...
|transformed to the equivalent function-call notation
...
|However, the operands are sequenced in the order
|prescribed for the built-in operator
 
Note the last sentence! This seems to guarantee the
sequencing even in
 
::std::cout << ++i << ++i << '\n';
 
, i.e., the first »++i« is evaluated first.
 
Also cppreference comments:
 
|cout << i << i++; // undefined behavior until C++17
 
, suggesting that this has not undefined behavior in C++17
anymore.
 
»en.cppreference.com/w/cpp/language/eval_order« gives
even more cases where expressions do not have UB anymore.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Sep 21 12:00AM +0100

On 20/09/2018 22:39, Rick C. Hodgin wrote:
 
> It explains the nature of God, and His from-the-beginning
> plan for man.  He's outside of time, and He's restoring us
> to that outside-of-time existence as well.
 
Nothing but numerous assertions without evidence which can be summarily
dismissed with evidence. Now fuck off.
 
/Flibble
 
--
"Suppose it's all true, and you walk up to the pearly gates, and are
confronted by God," Bryne asked on his show The Meaning of Life. "What
will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery
that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a
world that is so full of injustice and pain. That's what I would say."
David Brown <david.brown@hesbynett.no>: Sep 19 05:09PM +0200

On 19/09/18 15:38, Rick C. Hodgin wrote:
 
> As such, the evidence you are missing comes from a place outside of
> your ability to understand, just as a blind person cannot know what
> it's like to see if their eyes have never worked.
 
In other words, it is all circular logic - you can only see this
"evidence" once you believe in your god. As I said, that does not mean
it is not true, but it means you cannot demonstrate it to anyone else.
 
> it really is, rather than believing they also were deceived, and
> there really is a proper way to approach and follow God which does
> not involve heinous things.
 
I don't believe Jesus is at fault for the bad things done in his name.
I believe that there are many people who do bad things - they will use
whatever excuse they can find in order to achieve their goals. If that
means telling people Jesus wants them to donate money to you, or it
means telling people they will go to heaven if they kill the people you
are at war with, then there are always people who will abuse any idea or
belief.
 
So no, I don't blame Jesus - nor do I blame Christians as a group. Nor
do I blame some ancient mythical figures in a mythical garden, nor a
mythical anthropomorphism of evil. I blame individuals who do evil for
the evil they do. No more, no less.
 
The Jesus described in the OT sounds to me like a smart and sympathetic
character. He basically wanted people to be good to each other. He
wanted us to be respectful, tolerant, forgiving and loving - to care for
one another. As far as that goes, I fully agree with him. In addition
to that, he was a Jew and like the others around him, believed in the
Jewish god - and he wanted people to live in accordance to that. That
is fine for those who believe in such a god - I don't, so I am not
bothered by that aspect of his life.
 
I expect modern day Christians to be concerned with the divinity of
Jesus and that side of him - that is critical to their faith. But I
also expect modern day Christians to be followers of his moral
philosophy - tolerance, love, respect, forgiveness. When someone is
missing those aspects in their life - such as by their condemnation of
others, bigotry, denying people their rights, telling people that they
are evil, disrespecting them - that person is not following the
teachings of Jesus. That person is not being a good Christian, no
matter how often they read the Bible or how often they claim to be
teaching others about god.
 
If /you/ want to be a good Christian - and be a good follower of Jesus
as portrayed in the OT - you need to be asking yourself if you actually
are following his philosophy and his teaching. Did Jesus tell
homosexuals that they will be burned in hell forever? No, I don't think
so. Did Jesus burst into people's homes, or meeting rooms, and demand
that they listen to him? No. Did Jesus condemn people as being
possessed by the devil because they disagreed with him? No. He offered
to teach those who wanted to listen. People came to him to listen - he
did not force himself on others. They came to him because they could
see he was a good person, doing good things, and saying things of
interest to them - not because he kept butting in to every conversation,
and repeated the same tired old ideas again and again.
Juha Nieminen <nospam@thanks.invalid>: Sep 21 04:05AM

> Therefore
 
> ::std::cout << ++i << ++i << '\n';
 
> now is not undefined behavior anymore.
 
Didn't C++17 disambiguate quite many such things?
"Öö Tiib" <ootiib@hot.ee>: Sep 21 01:47AM -0700

On Friday, 21 September 2018 07:05:51 UTC+3, Juha Nieminen wrote:
 
> > ::std::cout << ++i << ++i << '\n';
 
> > now is not undefined behavior anymore.
 
> Didn't C++17 disambiguate quite many such things?
 
However the order of evaluation is defined there are lot of people who
expect it to be something different and so are confused with what it
does. Better not to write such code even when it is well-defined.
 
Also the results of order of evaluation poll of Herb Sutter
illustrate it:
https://herbsutter.com/2014/12/01/a-quick-poll-about-order-of-evaluation/
"Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid>: Sep 20 03:41PM -0700

On 9/20/2018 2:08 PM, Christian Gollwitzer wrote:
 
> OK, DK pronounces it as "deck" - but the argument doesn't convince me. A
> deck of cards would remind me of a stack structure, you can put a card
> on top and remove it, but how would I remove from the other end?
 
One can use a tail index to automatically find the end. Remove the card
by decrementing the tail.
guinness.tony@gmail.com: Sep 21 12:46AM -0700

On Thursday, 20 September 2018 22:08:39 UTC+1, Christian Gollwitzer wrote:
 
> > "A deque ... has some properties in common with a deck of cards,
> > and it is pronounced the same way."
 
> OK, DK pronounces it as "deck" - but the argument doesn't convince me.
 
I'm not sure it's an argument, as such. I imagine it's just DEK's personal
mnemonic for remembering the name. Of course, he could just read out his
own initials as an acronym, instead!
 
> A deck of cards would remind me of a stack structure, you can put a card
> on top and remove it, but how would I remove from the other end?
 
You're imagining the deck sitting on a surface? It can also be held in hand.
Card sharps have no problem removing cards from either the top or the bottom
of the deck, when dealing.
 
> Or is it thought that we have two stacks, which can be used to simulate a
> dequeue?
 
... that's *deque*. "dequeue" is an operation (the opposite of "enqueue").
Robert Wessel <robertwessel2@yahoo.com>: Sep 21 03:07AM -0500

On Thu, 20 Sep 2018 23:08:25 +0200, Christian Gollwitzer
>deck of cards would remind me of a stack structure, you can put a card
>on top and remove it, but how would I remove from the other end? Or is
>it thought that we have two stacks, which can be used to simulate a dequeue?
 
 
Hold the deck of cards in your hand. Dealing from either the top or
the bottom is trivial.
Lynn McGuire <lynnmcguire5@gmail.com>: Sep 20 06:21PM -0500

"Modern C++ Features – Quality-of-Life Features" by Arne Mertz
https://arne-mertz.de/2018/09/quality-of-life-features/
 
"The use of 'override' has definitely improved my Quality Of Life 🙂"
 
Yup.
 
Lynn
Ian Collins <ian-news@hotmail.com>: Sep 21 10:25AM +1200

On 21/09/18 10:21, Stefan Ram wrote:
> I suspect that the size of »int« (and of »long« and other types)
> is implementation-defined.
 
> But does the standard say so explicitly?
 
The standard states a minimum range, so I'd argue this is equivalent to
saying the size is implementation defined.
 
--
Ian.
James Kuyper <jameskuyper@alumni.caltech.edu>: Sep 20 10:17PM -0400

On 09/20/2018 06:25 PM, Ian Collins wrote:
 
>> But does the standard say so explicitly?
 
> The standard states a minimum range, so I'd argue this is equivalent to
> saying the size is implementation defined.
 
implementation-defined behavior is
 
"behavior, for a well-formed program construct and correct data, that
depends on the implementation and that each implementation documents"
(C++ 1.3.11).
"unspecified behavior where each implementation documents how the choice
is made" (C 3.4.1p1).
 
Behavior is implementation-defined only if the relevant standard
explicitly requires it to be. C 5.2.4.2p1 says "An implementation is
required to document all the limits specified in this subclause,
which are specified in the headers <limits.h> and <float.h>."
 
However, that does not mean that it's required to document the sizes of
those types. "The representations of all types are unspecified except as
stated in this subclause." (C 6.2.6.1p1). The size of a type is one
aspect of that type's representation, and the only thing that subclause
says about the size is what is implied by the immediately following
paragraph: that all non-bit-fields have a size that is an integer number
of bytes. That implication is supported by the fact that sizeof
expressions are required to have an integer type and also to return the
size of the type they are applied to.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Sep 21 12:39AM +0200

On 21.09.2018 00:25, Ian Collins wrote:
 
>>    But does the standard say so explicitly?
 
> The standard states a minimum range, so I'd argue this is equivalent to
> saying the size is implementation defined.
 
It refers to the C standard. And although it states that the C standard
is "incorporated" into the C++ standard, that part of the C++ standard
is inexplicably non-normative text. It's like someone's played politics.
 
 
Cheers!,
 
- Alf
bitrex <user@example.net>: Sep 20 07:16PM -0400

On 09/20/2018 06:39 PM, Alf P. Steinbach wrote:
> is inexplicably non-normative text. It's like someone's played politics.
 
> Cheers!,
 
> - Alf
 
Prostitution was legal in Rhode Island from circa late 1970s to 2009
because the state legislature accidentally forgot to make it explicitly
illegal.
Tim Rentsch <txr@alumni.caltech.edu>: Sep 20 04:48PM -0700


> [..scenarios that might overflow the program stack..]
 
> [...] running out of stack is UB,
 
This assertion is fairly common, but it isn't right. Running out
of stack space is not undefined behavior as the C standard defines
the term. A lot of people find this very counter-intuitive; let
me see if I can explain it.
 
The Standard defines the behavior of C programs. (In some areas
it also deals with the behavior of compilers, linkers, etc, but
that does not concern us here.) To define a behavior means to
specify how a program should behave. This is done by giving
specifications for individual program constructs, eg, expressions,
statements, and declarations, and separately giving higher-level
rules for how the component constructs are connected and joined
together.
 
The Standard specifies the behaviors of component elements and
their various interconnections in terms of an abstract machine.
The abstract machine doesn't have a stack, nor does it have any
notion of capacity or capacity limits. To say a program construct
or a program as a whole has defined behavior means there is a
specification for what actions must occur in the abstract machine.
Loosely speaking, behavior is defined "if the Standard tells us
what the abstract machine is supposed to do."
 
The situation of "running out of stack space" simply doesn't exist
inside the abstract machine. The defining semantic descriptions
cannot depend on such things, because the abstract machine has no
way to represent them. To say that another way, none of the
Standard's semantic descriptions are predicated on, or have
conditions of, things like there being enough memory capacity or
the stack not overflowing: the semantic descriptions must apply
whether those conditions exist (in the physical machine) or not.
Hence we know what the abstract machine is supposed to do, and
therefore the behavior is defined.
 
A common reaction at this point might ask "if the behavior is
defined, then where is it defined?" That's an understandable
question, but it is also a meaningless question. The Standard
specifies the behavior of /programs/; it does not specify the
behavior of /situations/. Try this exercise:
 
1. Write a program that runs out of stack but is otherwise
strictly conforming. (It's easy to do this.)
 
2. Identify the statement or declaration whose behavior is
undefined under the semantic descriptions given in the
Standard. (That claim should be supported by specific
references to relevant passages in the Standard.)
 
3. If no such statement or declaration can be identified,
then the program has no undefined behavior as the
Standard uses the term, and running out of stack space
doesn't change that.
 
If someone tries writing a program along these lines, I think
they will find that every expression, declaration, statement,
etc, has an explicit definition, and those definitions do not
depend on stacks, machine capacities, capacity limits, etc.
The Standard gives explicit definitions for behavior of program
elements, and these specifications apply /whether capacity
limits of physical hardware are exceeded or not/. Such things
do not exist in the abstract machine, and so the given semantic
descriptions continue to apply.
 
> there is no error recovery.
 
Here I think is the crux of the confusion. It's true, or at
least usually true, that running out of stack space blows up
a program. But that doesn't mean the program has undefined
behavior. Saying a program's behavior is defined doesn't make
any promises or guarantees about what the program /will/ do if
run on physical hardware. It means only that there is a
specification for what the program /should/ do. I think the
problem people have is they try to equate one with the other.
 
 
(P.S. The original context was C, and the above explanation is
written assuming that same context. AFAIK the same statements
apply for C++ and its ISO standard, but I am not as familiar
with the C++ standard, so please take that into account. I would
appreciate any pointers for passages in the C++ standard that
might be at odds with what is written above.)
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: