Sunday, July 1, 2018

Digest for comp.lang.c++@googlegroups.com - 19 updates in 7 topics

Juha Nieminen <nospam@thanks.invalid>: Jul 01 06:18PM

> }
 
> Well, ashamed of my lack of fluency in C++, I thought about porting that
> code to the new syntax. Then, I came to meet the "range" definition.
 
There's absolutely nothing wrong in iterating a container using
an "old-style" for statement. If you need the index value, do it
like that. A range-based for exists as a convenience if you just
need to traverse the entire container and don't need an index.
 
Btw, it's not safe to compare an int to size_t. (This is true
also in C.) Unless you are absolutely sure the size is small
enough.
 
(Also, if you really need to do something only to each second
element, why not increment the loop variable by 2?)
Juha Nieminen <nospam@thanks.invalid>: Jul 01 06:11PM


>> Of course they work. (Well, unless you consider the implicit use of
>> 'this' to be using the object "by pointer".)
 
> It is! That is exactly the point.
 
If you are going to nitpick like that, then there is no "by value"
manipulation of objects in C++ at all. All member functions get an
implicit 'this' "pointer", and all member variables are accessed
through it.
Sam <sam@email-scan.com>: Jul 01 09:21AM -0400

Soviet_Mario writes:
 
> have none about the sequence of scopes (the "order" the files are compiled
> or, maybe, linked).
> Is this relevant ?
 
The only thing that can be stated for certain here, is that the file
compilation order is always irrelevant.
 
Nothing further can be stated withut specific, concrete, examples.
 
> I tried to resort to include, but it didn't work ...
 
Trying random things, without a clear understanding of what the problem is,
is very unlikely to be very productive.
 
The first step towards solving a problem is understanding what the actual
problem is. Your entire vague, nebulous description indicates that you don't
seem to understand what the actual problem is, and can't even communicate
it, clearly.
Soviet_Mario <SovietMario@CCCP.MIR>: Jul 01 06:52PM +0200

Il 01/07/2018 15:21, Sam ha scritto:
> the file compilation order is always irrelevant.
 
> Nothing further can be stated withut specific, concrete,
> examples.
 
I had a project (autogenerated) by QT creator, consisting of
two files : one with MAIN app, the other for initing the GUI
 
Then I added a MY.CPP further file with some generic class
declaration.
 
Building all I obtained errors like "type class XXX is not
defined".
 
When I embedded the same code and declarations from MY.CPP
either in Main.CPP or in MainWindow.CPP, the build went
plain without errors.
 
So I'm trying to understand where to put code and why
splitting it in handy files won't work.
There might be wrong link settings ? I can't find them (I
used to use VStudio, but I'm trying to move to QTcreator and
I'm less than newbie in this IDE).
There might be other aspect in declarations I miss / forgot
(like extern directives ?)
 
 
I've a vague memory that extern variables without static had
global scope (with static they were restricted to file
scope). As far as class declaration I've no memory of their
scope and if/how to alter it.
 
 
>> I tried to resort to include, but it didn't work ...
 
> Trying random things, without a clear understanding of what
> the problem is, is very unlikely to be very productive.
 
I'm asking in order to understand
 
> what the actual problem is. Your entire vague, nebulous
> description indicates that you don't seem to understand what
> the actual problem is,
 
true
 
> and can't even communicate it, clearly.
 
a consequence of the former :)
 
I tried to explain with a generic example ... I dunno if it
will be useful
 
Ciao
 
 
--
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
Soviet_Mario - (aka Gatto_Vizzato)
Paavo Helde <myfirstname@osa.pri.ee>: Jul 01 08:45PM +0300

On 1.07.2018 19:52, Soviet_Mario wrote:
> declaration.
 
> Building all I obtained errors like "type class XXX is not
> defined".
 
First you need to figure out if these were compiler errors or linker
errors as this will narrow the location of the bug (in broad terms, is
the problem in .h or in .cpp files).
 
In C++, everything used by the code must be first declared, typically in
included header files; if it's not, then you get compiler errors.
 
The declared things must be also actually defined, typically in cpp
files. For linking the whole program the linker needs to have all used
symbols defined somewhere; if this is not the case, you get linker errors.
 
Most people in this group can say by a single glance on an error message
if it is coming from the compiler or linker, but of course it never did
occur to you to post an actual error message.
 
 
> When I embedded the same code and declarations from MY.CPP
> either in Main.CPP or in MainWindow.CPP, the build went
> plain without errors.
 
Seems like either a namespace problem or that you did not include MY.CPP
in the build properly.
 
Construct a minimal example demonstrating the problem, post the code and
the actual error messages.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jul 01 09:02AM -0400

On 06/30/2018 07:17 AM, Bart wrote:
> If min/max were operators, so that they could be written as 'a max b',
> perhaps as well as 'max(a,b)', then the following becomes possible:
 
>    a max= b;
 
 
You won't find a better syntax than:
 
a /\= b;
 
It takes a moment to learn, but once you get the concept it's easy to
use everywhere.
 
a = (b /\ c) * d;
 
I've thought about your comment regarding it not working due to the
use of the \ character in certain circumstances. But, this wouldn't
be a \ character in and of itself, but would be the /\ combination in
some cases, and \/ in others. The compiler would have no issues in
parsing that.
 
--
Rick C. Hodgin
Wouter Verhelst <w@uter.be>: Jul 01 03:27PM +0200

On 01-07-18 11:08, Bart wrote:
> I don't use an optimising compiler.
 
Your loss.
 
> ints, and 'max' is a function (not a macro, not even an inline function)
> involves executing some 14 instructions, including call, return and
> branches [on x64].
 
Sure, but on a decent optimizing compiler there won't be a difference --
and no need to complicate the language with extra operators etc.
 
To me, that is a huge benefit.
Ben Bacarisse <ben.usenet@bsb.me.uk>: Jul 01 05:14PM +0100


>>    a max= b;
 
> You won't find a better syntax than:
 
> a /\= b;
 
Except that (a) there is an existing implementation that uses <? and >?;
(b) your symbols are the reverse of what some people would expect; and
(c) there is an ambiguity to resolve when /\ oecus at the end of a
line.
 
There is a strong argument against proliferating incompatible extensions
to C. (b) is, in my opinion, comparatively minor, but (c) must be
resolved in such a way as to respect the meaning of existing code making
the new operator a little off (see below).
 
> be a \ character in and of itself, but would be the /\ combination in
> some cases, and \/ in others. The compiler would have no issues in
> parsing that.
 
The problem is not the compiler -- you can make a compiler that
implements whatever rules you want about /\. The problem is whether or
not you break existing code because this
 
a = b /\
2;
 
already has a meaning. You can, of course, write the new rules so that
the meaning of such code does not change, but it makes the new operator
a little odd in that you can't break an expression across lines after
it.
 
--
Ben.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jul 01 12:35PM -0400

On 07/01/2018 12:14 PM, Ben Bacarisse wrote:
 
>> You won't find a better syntax than:
 
>> a /\= b;
 
> Except that (a) there is an existing implementation that uses <? and >?;
 
I considered <? and >? when mentioned before, but they're not for me.
I think /\ and \/ convey the meaning very clearly, and I've been con-
sidering the existing mathematical use of the opposite direction, and
I really think they got it wrong. Especially when the use a closed
triangle.
 
My opinion. In CAlive, it will be as I have indicated. Other C-like
languages, including C or C++, are able to implement them however they
choose ... though I do not believe they will ever be implemented in C
or C++, so it's a non-issue.
 
My original inquiry was to see if there was a min or max operator. I
have never seen one in my 30+ years of programming. I could've used
one in database programming a great many time. Have always had to use
the min(a,b) syntax. An operator seems a better choice.
 
> the meaning of such code does not change, but it makes the new operator
> a little odd in that you can't break an expression across lines after
> it.
 
 
Does the \ work everywhere in C? Or just in a #define block? I don't
think I've ever seen it anywhere else.
 
The rule has been written, Ben B. In CAlive, the native interpretation
of your example will be as "a = b /\ 2;":
 
--
Rick C. Hodgin
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jul 01 12:36PM -0400

On 07/01/2018 12:30 PM, Rick C. Hodgin wrote:
> The rule has been written, Ben B. In CAlive, the native interpretation
> of your example will be as "a = b /\ 2;":
 
To be clear about this, in CAlive if you wanted to use your example of
a continuation it would need to be written as:
 
a = b /\ \
2;
 
--
Rick C. Hodgin
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jul 01 12:44PM -0400

On 07/01/2018 12:37 PM, Bart wrote:
>> of your example will be as "a = b /\ 2;":
 
> Is /\ min or max? Because, you know, one end is small so it could mean
> min, but then the other end is fat so it could be max.
 
You've mentioned that before.
 
> Or are you supposed to use device such as that /\ looks a bit like 'A',
> which is the second letter of MAX? Assuming it is actually max.
 
The arrow points toward the value being sought. The up arrow /\ is for
max (upper value), and the down arrow \/ is for min (lower value).
 
People wouldn't use the new operator without learning what it is. It
won't be confusing to people who take advantage of the new feature. If
someone came across the syntax in code and didn't know what it meant, a
nearby comment may explain it, or a simple test.ca program compiled in
CAlive would let them see the result.
 
--
Rick C. Hodgin
Bart <bc@freeuk.com>: Jul 01 05:47PM +0100

On 01/07/2018 14:27, Wouter Verhelst wrote:
 
> Sure, but on a decent optimizing compiler there won't be a difference --
> and no need to complicate the language with extra operators etc.
 
> To me, that is a huge benefit.
 
Don't forget the cost also of having 'max', if implemented as a macro
expanded to that safe macro at each instance of max, of expanding that
macro each time max occurs, reparsing the tokens again, building that
bit of AST, doing the same optimisations and the same <max> pattern
recognition and the conversion into intrinsic versions or into optimised
code, over and over again.
 
This is the extra cost of having these things defined on top of the
language instead of being built-in. In the case of C++, this seems to
apply to just about everything in it.
 
Yes it is nice to have a good optimiser, but there's plenty more it can
spend its time on. Implementing 'max' etc efficiently can be done once,
instead of in N different places in a program, every time it is
compiled, and for every other programmer and application that uses it.
 
--
bart
Bart <bc@freeuk.com>: Jul 01 06:41PM +0100

On 01/07/2018 17:44, Rick C. Hodgin wrote:
 
>> which is the second letter of MAX? Assuming it is actually max.
 
> The arrow points toward the value being sought. The up arrow /\ is for
> max (upper value), and the down arrow \/ is for min (lower value).
 
So is the max value at the top or the bottom?
 
If the max value at the top, and /\ means MAX, then that's the opposite
of how two values, or a set of values if sorted, are usually displayd on
a page.
 
I'm sorry but it's completely unintuitive. I've probably said that
before too.
 
--
bart
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jul 01 01:45PM -0400

On 07/01/2018 01:41 PM, Bart wrote:
 
> If the max value at the top, and /\ means MAX, then that's the opposite
> of how two values, or a set of values if sorted, are usually displayd on
> a page.
 
Read carefully this time:
 
The arrow points toward the value being sought. The up arrow /\ is for
max (upper value), and the down arrow \/ is for min (lower value).
 
If that's not clear ... well, I'm sorry.
 
> I'm sorry but it's completely unintuitive. I've probably said that
> before too.
 
You did. And I disagree. I've shown the idea to developers in real
and they've been impressed. To them it was completely intuitive.
 
--
Rick C. Hodgin
Paavo Helde <myfirstname@osa.pri.ee>: Jul 01 08:08PM +0300

On 1.07.2018 14:35, Manfred wrote:
 
 
> will compile, but be ineffective - most annoyingly, /silently/
> ineffective (unless you have a compiler that can catch this stuff, and
> you instruct it to do so).
 
This is one of the few occasions I have found macros useful. All my
mutex locks go through macros which define a lock variable, e.g:
 
SCOPED_LOCK(g_pages_mutex);
 
This has several benefits IMO:
 
1. Avoids stumbling upon the most vexing parse which you brought up.
 
2. Can easily add, remove and modify run-time checks (potentially in
debug mode compilation only) for trouble-shooting the multi-threading
issues: checking against locking a non-recursive mutex recursively,
checking against locking mutexes in inconsistent order, i.e. potential
deadlocks, monitoring the duration of locks etc. There are diagnostic
tools to achieve similar goals without source code modifications, but in
my experience they have appeared either non-effective or too slow to
accomplish anything.
 
3. Can portably add filename and line number in the diagnostics for
above checks.
 
4. The lock variable name is hidden which is fine as it does not matter
most of the time (it's needed only when one wants to wait on the mutex).
Tim Rentsch <txr@alumni.caltech.edu>: Jul 01 10:29AM -0700


> Or would it be better to replace the commas with variable names, and
> if so, what variable names would/could facilitate at-a-glance
> grokability?
 
What this suggests to me is that RAII is the wrong model to think
about what's going on here. The objects being constructed aren't
really managing a resource in the normal sense; what they are
doing is wrapping some prologue and epilogue code around the
subject code 'app::run()'. This doesn't have to be done using
classes. Another way to get the wrapping to happen is to use a
function that takes a lambda argument. To illustrate (disclaimer:
code just typed in, not compiled):
 
if( args[1] == "--faux-text" )
{
with_faux_text_run( [](){ app::run(); } );
}
else
{
with_stream_detection_run( [](){ app::run(); } );
}
 
Then, since functions are (able to be turned into) values, we can
factor and simplify further:
 
bool faux = args[1] == "--faux-text";
auto wrapper = faux ? with_faux_text_run : with_stream_detection_run;
 
wrapper( [](){ app::run(); } );
 
Also, I suspect the two functions will be easier to write and
more straightforward to understand than their corresponding
classes.
 
To me this formulation seems preferable to a version with class
construction. A weakness is it would need to protect against
exceptions being thrown. That could be done inside each function,
either with try/catch, or with a construction done inside each
function. Depending on their internals, the two functions might
choose different approaches, or in some cases not have to worry
about exceptions at all. So what we're seeing is a functional
approach that adds a layer of abstraction, to allow simplifying
the caller.
Tim Rentsch <txr@alumni.caltech.edu>: Jul 01 06:55AM -0700


> This perhaps comes back to the point that the language in question
> will decide what is "pure" in the context of whatever compiler
> optimizations it is trying to support by adopting that keyword.
 
My impression is that "pure" in the sense of "not having side
effects" is more common and more usual in the general programming
community. It aligns with usage in the functional programming
community, where language features are described as "pure" or
"impure" according to whether side-effects may occur. It's
consistent with my memory of learning to distinguish pure Lisp,
"sometimes humorously referred to as poor Lisp" (admittedly not a
very reliable data point). Furthermore the property of being
side-effect free (but possibly accessing state that is otherwise
mutable) is a useful distinction to make, both for operators and
functions, because a set of such operations may be arbitrarily
reordered without changing the meaning, regardless of whether
mutable state is accessed. These items plus the existence of the
term "referentially transparent", which unambiguously has the
stronger meaning, lead me to think it is better to use "pure"
to mean just side-effect free, and "referentially transparent"
for the stronger meaning. In any case it seems best to limit
"pure" to mean no more than one of those two meanings, and not
add another definition which would further confuse the issue.
 
>> }
 
> Kudos: very clever. I am astonished that constexpr functions can take a
> reference to a non-constexpr function as an argument and then call it.
 
Thank you, I can live for a month on a compliment, as the saying
goes. For myself, I wasn't sure when I tried it that it would
work, but I wasn't surprised when it did; I would have been more
surprised if it didn't.
 
> The values of 'a', 'b' and 'c' presumably are not computed at compile
> time because the argument passed to 'bar' ('impure') is not constexpr.
 
Right. In principle they could be in this example, since the
compiler can see all the places 'impure' is used, and figure
things out in advance. But neither g++ nor clang was smart
enough to do so, and certainly it cannot be done in general.
 
> might, or might not, be constexpr, and when it is then 'foo' is (as
> required) called at compile time, as when initializing 'three'. But it
> seems perverse.
 
I don't think of it as a hole at all. A constexpr function is
just a regular function, except with certain restrictions that
guarantee it can be evaluated at compile time, _provided_ certain
things are true of the arguments given. But if the return value
doesn't need to be constexpr, a constexpr function can be used
just like a regular function[*]. I see this quality as a
strength, not a weakness.
 
[*] Disclaimer: I believe. I find the C++ standard very hard
reading, and in this case I didn't even try to read what it
requires in such cases.
Tim Rentsch <txr@alumni.caltech.edu>: Jul 01 08:12AM -0700

> it should be a "purely virtual function" then, which makes a lot of
> sense, other than a "pure virtual function" which is pure and a
> virtual function - but I'm not a native speaker.
 
To some extent I share your reaction. I wouldn't use "purely
virtual function" (although I did think of it), because it
somehow doesn't mean the right thing, even if I'm not sure of
exactly what it does or should mean.
 
So, on further reflection, I think a different characterization is
probably more appropriate here. Rather than thinking of "pure" as
modifying "virtual" (surely "pure" is not meant to modify the word
"function"?), suppose we think of "virtual function" as a compound
noun, so "pure virtual function" should be read as if it were
"pure (virtual function)", rather than "pure, virtual function",
which would mean a function that is both pure and virtual. The
compound noun idea is a little better, but still seems a bit off.
What I think is better is to take "pure virtual" as a compound
/adjective/, making a new meaning for the combination; that would
mean "pure virtual function" should be read as "(pure virtual)
function". In many cases compound adjectives are hyphenated, but
not always, and here I think it reads better without a hyphen.
Also I think "(pure virtual) function" is how most C++-ers think
of the term.
 
 
> and a "pure" function "side-effect free" function or simply
> "function", whereas the thingy with side-effects could be a
> "procedure" or "subroutine".
 
It is fashionable in programming languages today to use keywords
(rather than some symbolic syntax) kind of as much as possible.
Personally I think that's a bad trend. I would rather see just
 
int member() = 0;
 
to mean a (pure virtual) function. As someone pointed out, the
'=0' makes 'virtual' redundant, so why not just leave it off?
(Or maybe leaving it off could be optional.) Notation helps.
For centuries mathematicians wrote without symbols, just in
ordinary language. That would be unthinkable today, and IMO
rightly so. Or, take another example, the physical laws for
electromagnetic fields. When Maxwell orginally wrote his famous
equations, there were not four equations but sixteen equations,
because vector notation hadn't been invented yet. No one would
consider doing that today. So it seems rather strange to see
programming languages embracing a more verbal (and more verbose)
form of expression.
Tim Rentsch <txr@alumni.caltech.edu>: Jul 01 07:28AM -0700

>> point.
 
> He doesn't appear to be capable of arguing in anything other than
> Boolean.
 
That doesn't mean you should do the same. In fact why argue with
him at all? It's clear you aren't going to change his mind on
this point. But taking a more detached view might change some
other people's minds, which I expect would work to your advantage
here.
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: