Friday, January 24, 2020

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

Bart <bc@freeuk.com>: Jan 24 01:06AM

On 22/01/2020 19:04, Christian Gollwitzer wrote:
 
> What good reasons are left for a literal goto? I can see it in C for
> error handling (because it lacks exceptions) - in C++ there is hardly a
> good reason IMHO.
 
(Copied from a post elsewhere)
 
I still use it [goto], although rarely. For example:
 
For temporary code, until it can be done properly
 
To temporarily by-pass code or to cut to the action for debugging
 
When translating an algorithm or code from another language, that
itself uses goto
 
When using this language as a target language for another, and I
need goto to emulate the control flow of a statement that has no
direct equivalent
 
To implement state machines
 
Via inline assembly, to deal with error recovery across functions
(although it's a long time since I used that); but also to implement
threaded code in interpreters
 
Or just when I can't be bothered with too-convoluted code, and goto
is the fastest and simplest way of expressing my intent
 
Even with this, I think my incidence of using goto is once per 400 lines
or so, so 'spaghetti code' is unlikely.
 
I would not design a new language without goto.
Bart <bc@freeuk.com>: Jan 24 01:08AM

> case rubbish (lambda capture initialisation, digit seperators, auto returns)
> and pointless STL classes and defs (optional, variant, byte, any, data())
> that they've thrown in since 2011.
 
Digit separators are genuinely useful (and also incredibly simple to
implement, compared to the rest of that lot). What's the problem with them?
Bo Persson <bo@bo-persson.se>: Jan 24 10:07AM +0100

On 2020-01-24 at 02:06, Bart wrote:
>     is the fastest and simplest way of expressing my intent
 
> Even with this, I think my incidence of using goto is once per 400 lines
> or so, so 'spaghetti code' is unlikely.
 
I find that an extremely high use of goto. Would rather expect once in a
million lines, or so.
 
 
Bo Persson
Paavo Helde <myfirstname@osa.pri.ee>: Jan 24 11:36AM +0200

On 24.01.2020 11:07, Bo Persson wrote:
>> lines or so, so 'spaghetti code' is unlikely.
 
> I find that an extremely high use of goto. Would rather expect once in a
> million lines, or so.
 
FWIW, I just grepped our C++ codebase (600 KLOC) for goto, it appears
there is one goto per 8000 lines. This is a bit surprising, I did not
expect so many gotos.
Bart <bc@freeuk.com>: Jan 24 12:19PM

On 24/01/2020 09:07, Bo Persson wrote:
>> lines or so, so 'spaghetti code' is unlikely.
 
> I find that an extremely high use of goto. Would rather expect once in a
> million lines, or so.
 
IIRC 'goto' in the Linux kernel code was more like once in 200 lines.
 
Some CPython sources I've just tested (all .c files, not .h, in the ./py
directory combined into one 44Kloc file) use "goto " once per 230 lines.
 
On Tiny C sources (again only .c files in main folder), it's once per 95
lines.
 
On Lua sources however, it's once per 430 lines. (Neither Lua nor Python
projects have 'goto' in the languages they implement.)
 
Your once in a million lines sounds extreme. None of my projects are
anywhere near that size. goto is inelegant but if it's the simplest way
to code something, then I will use it.
 
(On my own biggest project its once per 500 lines. This in a language
that allows nested loop breaks.)
boltar@nowhere.org: Jan 24 12:27PM

On Fri, 24 Jan 2020 01:08:54 +0000
>> that they've thrown in since 2011.
 
>Digit separators are genuinely useful (and also incredibly simple to
>implement, compared to the rest of that lot). What's the problem with them?
 
Well ok, I'm sure they can make the code a little bit more readable. But in
the scheme of things that it would be nice to have in C++ they were hardly
top of the list whereas named loops is an extremely useful language construct
and should be easy to implement.
Bo Persson <bo@bo-persson.se>: Jan 24 02:19PM +0100

On 2020-01-24 at 13:19, Bart wrote:
 
> Your once in a million lines sounds extreme. None of my projects are
> anywhere near that size. goto is inelegant but if it's the simplest way
> to code something, then I will use it.
 
It wasn't so much about project sizes as about coding for years between
each time a goto has seemed even slightly useful.
 
 
Took a quick look at the Tiny C code (random choice tccasm.c) and found
some examples of goto between different cases of a switch statement,
goto from the if branch to the else part of an if-statement.
 
And this beauty:
 
redo:
if (tok == '#') {
/* horrible gas comment */
while (tok != TOK_LINEFEED)
next();
} else if (tok >= TOK_ASMDIR_FIRST && tok <= TOK_ASMDIR_LAST) {
asm_parse_directive(s1, global);
} else if (tok == TOK_PPNUM) {
const char *p;
int n;
p = tokc.str.data;
n = strtoul(p, (char **)&p, 10);
if (*p != '\0')
expect("':'");
/* new local label */
asm_new_label(s1, asm_get_local_label_name(s1, n), 1);
next();
skip(':');
goto redo;
} else if (tok >= TOK_IDENT) {
/* instruction or label */
opcode = tok;
next();
if (tok == ':') {
/* new label */
asm_new_label(s1, opcode, 0);
next();
goto redo;
} else if (tok == '=') {
set_symbol(s1, opcode);
goto redo;
} else {
asm_opcode(s1, opcode);
}
}
 
where you have 3 goto's back to redo, instead of a for(;;) and breaks
for the cases when you don't want to redo anything. Not an example to
follow!
 
 
Bo Persson
cdalten@gmail.com: Jan 24 05:39AM -0800

On Tuesday, November 5, 2019 at 11:45:23 AM UTC-8, Paavo Helde wrote:
 
> IMO, wrapping integers (signed or unsigned) are an example of
> "optimization which nobody asked for", and they are there basically only
> because the hardware happened to support such operations.
 
And not having this would cause things like TCP/IP to break since parts use this to construct what are known Abelian Groups.
Bart <bc@freeuk.com>: Jan 24 02:11PM

On 24/01/2020 13:19, Bo Persson wrote:
 
> where you have 3 goto's back to redo, instead of a for(;;) and breaks
> for the cases when you don't want to redo anything. Not an example to
> follow!
 
That does look poor. But bear in mind, this block is already part of an
outer for(;;) loop.
 
With nested loops, and with a lot of the code using switch rather than
if-else, 'break' is under some pressure: you can't use it to jump out of
a loop if inside a switch, and you can't use it to jump out of an outer
loop whether in a switch or not.
 
(And conversely, if you have 'break' inside an if-else chain inside a
loop, you can't convert the if-else chain into a switch, without finding
alternatives to those breaks, if you've even spotted the issue.)
 
I think this example belongs to my first use-case: while developing, you
temporarily put in thesedirty fixes to get things to work, with a mind
to reviewing later when you have the full picture of the final working
code. This apparently never got done.
 
But remember, Tiny C is probably the world's fastest C compiler; you
have to cut it some slack!
 
(Also, I believe Tiny C started off as an IOCCC entry.)
Paavo Helde <myfirstname@osa.pri.ee>: Jan 24 05:53PM +0200

>> "optimization which nobody asked for", and they are there basically only
>> because the hardware happened to support such operations.
 
> And not having this would cause things like TCP/IP to break since parts use this to construct what are known Abelian Groups.
 
If you mean the "Internet checksum", then my first google hit says it is
16-bit and uses one's complement addition:
 
"One's complement addition can be implemented by "end-round-carry
addition": when a carry bit is produced using conventional (two's
complement) addition, the carry is added back in as a 1 value."
 
Does not look to me like the C standard unsigned wrapover behavior.
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 24 05:26PM

On Fri, 2020-01-24, Bart wrote:
> lines.
 
> On Lua sources however, it's once per 430 lines. (Neither Lua nor Python
> projects have 'goto' in the languages they implement.)
 
Those are all C examples. The context here was C++.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 24 05:31PM

On Fri, 2020-01-24, Paavo Helde wrote:
> addition": when a carry bit is produced using conventional (two's
> complement) addition, the carry is added back in as a 1 value."
 
> Does not look to me like the C standard unsigned wrapover behavior.
 
He may be referring to how TCP sequence numbers wrap.
 
Or to something else. Anyway, nothing that would be impossible to do
in a parallel universe where C's unsigneds don't wrap.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Bart <bc@freeuk.com>: Jan 24 05:35PM

On 24/01/2020 17:26, Jorgen Grahn wrote:
 
>> On Lua sources however, it's once per 430 lines. (Neither Lua nor Python
>> projects have 'goto' in the languages they implement.)
 
> Those are all C examples. The context here was C++.
 
I can't see much in C++ that would eliminate the use-cases for goto in C.
 
C++ has exceptions that work across functions, but C doesn't even use
goto for those
Paavo Helde <myfirstname@osa.pri.ee>: Jan 24 10:27PM +0200

On 24.01.2020 19:35, Bart wrote:
 
> I can't see much in C++ that would eliminate the use-cases for goto in C.
 
> C++ has exceptions that work across functions, but C doesn't even use
> goto for those
 
How come? How one can sanely cope with error checking in C without goto,
if there is even a single resource to be released before error return?
 
In a single .c file I have 57 gotos, that's about the same amount as for
the whole C++ codebase of over half a million lines.
Ian Collins <ian-news@hotmail.com>: Jan 25 11:06AM +1300

On 25/01/2020 06:35, Bart wrote:
 
> I can't see much in C++ that would eliminate the use-cases for goto in C.
 
> C++ has exceptions that work across functions, but C doesn't even use
> goto for those
 
Our code base (about 2500 C++ source files) has few exceptions and not
one goto. There really is no need for it.
 
--
Ian.
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 24 10:12PM

On Fri, 2020-01-24, Bart wrote:
>>> projects have 'goto' in the languages they implement.)
 
>> Those are all C examples. The context here was C++.
 
> I can't see much in C++ that would eliminate the use-cases for goto in C.
 
Of course not -- how could a feature in language X eliminate the need
for another feature in language Y?
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
David Brown <david.brown@hesbynett.no>: Jan 25 12:05AM +0100

On 24/01/2020 13:19, Bart wrote:
 
> Your once in a million lines sounds extreme. None of my projects are
> anywhere near that size. goto is inelegant but if it's the simplest way
> to code something, then I will use it.
 
I can only ever remember /once/ using "goto" in C code (and that was
only for a while - it got removed after a refactoring). I don't know
how many lines I have written over the years, in all my work - I don't
think it would be a million lines, but it is a great deal. Different
people code in different ways and have different requirements.
 
I suspect you'll find "goto" occurring most in either badly written and
badly structured code (we all know this kind of code exists, but lets
ignore it for now), for generated code (again, we'll ignore that), or
code where there is a strong emphasis on good performance even in the
face of poor compilers (or no optimisation enabled) and older C
standards. For this kind of thing, there are going to be more
situations where "goto" (or other unstructured code practices, like
non-trivial switch case fall-throughs) can be a definite help in getting
efficient results.
 
When you have better tools (or don't care about performance), there are
many more options available. You can re-factor code into smaller
functions, and leave nested loops with a "return" - in the knowledge
that the compiler will inline these single-use static functions and give
you just as efficient results. You can add extra booleans for flags and
put them in the conditionals for the loops - knowing the compiler will
turn them into goto's. You can duplicate code (not often a great idea,
but sometimes the neatest and clearest solution), knowing the compiler
will merge duplicate code sections without manual goto's or switch case
fall-throughs.
 
I am all in favour of using a coding technique if I think it is the
simplest, clearest, and most maintainable option. The reason I don't
use goto's myself is that I have never found it to be the best choice
for my code - not because of a particular allergy against it.
 
aminer68@gmail.com: Jan 24 12:15PM -0800

Hello,
 
 
Functional Programming Doesn't Work (and what to do about it)
 
"After spending a long time in the functional programming world, and using Erlang as my go-to language for tricky problems, I've finally concluded that purely functional programming isn't worth it."
 
Read more here:
 
https://prog21.dadgum.com/54.html
 
 
Thank you,
Amine Moulay Ramadne.
Siri Cruise <chine.bleu@yahoo.com>: Jan 24 01:38PM -0800

In article
<c3b29c33-e4eb-4e31-8b09-ee4fb0aee1d7@googlegroups.com>,
 
> "After spending a long time in the functional programming world, and using
> Erlang as my go-to language for tricky problems, I've finally concluded that
> purely functional programming isn't worth it."
 
Functional programming with memoing does.
 
 
A(0, 0) = 1, 1 iterations.
M(0, 0) = 1, 1 iterations.
A(4, 0) = 13, 107 iterations.
M(4, 0) = 13, 33 iterations.
A(0, 4) = 5, 1 iterations.
M(0, 4) = 5, 0 iterations.
A(1, 1) = 3, 4 iterations.
M(1, 1) = 3, 0 iterations.
A(2, 2) = 7, 27 iterations.
M(2, 2) = 7, 0 iterations.
A(3, 4) = 125, 10307 iterations.
M(3, 4) = 125, 283 iterations.
 
set ak 0
proc A {m n} {
incr ::ak
expr {
$m==0 ? [+1 $n]
: $n==0 ? [A [-1 $m] 1]
: [A [-1 $m] [A $m [-1 $n]]]
}
}
 
set mk 0
array set memo {}
proc M {m n} {
global memo
if {[info exists memo($m,$n)]} {return $memo($m,$n)}
incr ::mk
set Mmn [expr {
$m==0 ? [+1 $n]
: $n==0 ? [M [-1 $m] 1]
: [M [-1 $m] [M $m [-1 $n]]]
}]
set memo($m,$n) $Mmn
return $Mmn
}
 
proc +1 {v} {expr {$v+1}}
proc -1 {v} {expr {$v-1}}
 
--
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted. @
'I desire mercy, not sacrifice.' /|\
The first law of discordiamism: The more energy This post / \
to make order is nore energy made into entropy. insults Islam. Mohammed
aminer68@gmail.com: Jan 24 12:39PM -0800

Hello,
 
 
Functional programming: A step backward
 
Unlike imperative code, functional code doesn't map to simple language constructs. Rather, it maps to mathematical constructs.
 
We've gone from wiring to punch cards to assembler to macro assembler to C (a very fancy macro assembler) and on to higher-level languages that abstract away much of the old machine complexity. Each step has taken us a little closer to the scene in "Star Trek IV" where a baffled Mr. Scott tries to speak instructions into a mouse. After decades of progress in making programming languages easier for humans to read and understand, functional programming syntax turns back the clock.
 
Functional programming addresses the concurrency problem of state but often at a cost of human readability. Functional programmming may be entirely appropriate for many circumstances. Ironically, it might even help bring computer and human languages closer together indirectly through defining domain-specific languages. But its difficult syntax makes it an extremely poor fit for general-purpose application programming. Don't jump on this bandwagon just yet — especially for risk-averse projects.
 
 
Read more here:
 
https://www.javaworld.com/article/2078610/functional-programming--a-step-backward.html
 
 
Thank you,
Amine Moulay Ramdane.
Daniel <danielaparker@gmail.com>: Jan 23 10:17PM -0800

Can someone explain what is the difference between is_standard_layout and is_pod, and why the latter is being deprecated in 2020?
 
Thanks,
Daniel
Bo Persson <bo@bo-persson.se>: Jan 24 10:14AM +0100

On 2020-01-24 at 07:17, Daniel wrote:
> Can someone explain what is the difference between is_standard_layout and is_pod, and why the latter is being deprecated in 2020?
 
The is_pod tests several conditions that have been separated into
is_standard_layout and is_trivial.
 
So, is_pod is no longer used by the standard library (except as the
deprecated type trait).
 
 
Bo Persson
James Kuyper <jameskuyper@alumni.caltech.edu>: Jan 23 10:25PM -0500

> On Wednesday, 22 January 2020 09:58:35 UTC, bol...@nowhere.org wrote:
...
>> 2 warnings and 3 errors generated.
 
> It does if you use the C++ compiler (you're using the C compiler, above).
 
> C doesn't have raw string literals; C++ does.
 
How did you conclude that c++ is the name of a C compiler?
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: