Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #156861 > unrolled thread
| Started by | kevin shell <kevin@fedora.osfans.org> |
|---|---|
| First post | 2020-12-02 16:42 +0800 |
| Last post | 2020-12-11 19:27 -0800 |
| Articles | 20 on this page of 114 — 24 participants |
Back to article view | Back to comp.lang.c
Effective uses of c `goto' statement kevin shell <kevin@fedora.osfans.org> - 2020-12-02 16:42 +0800
Re: Effective uses of c `goto' statement Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-12-02 01:07 -0800
Re: Effective uses of c `goto' statement Anton Shepelev <anton.txt@gmail.com> - 2020-12-02 20:18 +0300
Re: Effective uses of c `goto' statement Anton Shepelev <anton.txt@gmail.com> - 2020-12-02 20:56 +0300
Re: Effective uses of c `goto' statement David Brown <david.brown@hesbynett.no> - 2020-12-02 19:30 +0100
Re: Effective uses of c `goto' statement Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-02 19:35 +0000
Re: Effective uses of c `goto' statement David Brown <david.brown@hesbynett.no> - 2020-12-02 21:05 +0100
Re: Effective uses of c `goto' statement Vir Campestris <vir.campestris@invalid.invalid> - 2020-12-02 18:07 +0000
Re: Effective uses of c `goto' statement David Brown <david.brown@hesbynett.no> - 2020-12-02 19:33 +0100
Re: Effective uses of c `goto' statement Siri Cruise <chine.bleu@yahoo.com> - 2020-12-02 10:22 -0800
Re: Effective uses of c `goto' statement Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-02 20:18 +0000
Re: Effective uses of c `goto' statement David Brown <david.brown@hesbynett.no> - 2020-12-02 23:16 +0100
Re: Effective uses of c `goto' statement Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-03 01:31 +0000
Re: Effective uses of c `goto' statement David Brown <david.brown@hesbynett.no> - 2020-12-03 08:39 +0100
Re: Effective uses of c `goto' statement Siri Cruise <chine.bleu@yahoo.com> - 2020-12-02 23:48 -0800
Re: Effective uses of c `goto' statement Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-03 17:49 +0000
Re: Effective uses of c `goto' statement Bonita Montero <Bonita.Montero@gmail.com> - 2020-12-03 17:09 +0100
Re: Effective uses of c `goto' statement Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-05 08:28 -0800
Re: Effective uses of c `goto' statement Richard Damon <Richard@Damon-Family.org> - 2020-12-05 12:41 -0500
Re: Effective uses of c `goto' statement Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 05:03 -0800
Re: Effective uses of c `goto' statement Richard Damon <Richard@Damon-Family.org> - 2020-12-06 08:51 -0500
Re: Effective uses of c `goto' statement Richard Damon <Richard@Damon-Family.org> - 2020-12-06 08:56 -0500
Re: Effective uses of c `goto' statement Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 18:43 -0800
Re: Effective uses of c `goto' statement Öö Tiib <ootiib@hot.ee> - 2020-12-06 05:58 -0800
Re: Effective uses of c `goto' statement Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 16:54 -0800
Re: Effective uses of c `goto' statement Siri Cruise <chine.bleu@yahoo.com> - 2020-12-05 10:01 -0800
Re: Effective uses of c `goto' statement Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 04:55 -0800
Re: Effective uses of c `goto' statement Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-03 21:20 -0800
Re: Effective uses of c `goto' statement Siri Cruise <chine.bleu@yahoo.com> - 2020-12-03 21:50 -0800
Re: Effective uses of c `goto' statement Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-03 23:06 -0800
Re: Effective uses of c `goto' statement Siri Cruise <chine.bleu@yahoo.com> - 2020-12-04 00:27 -0800
Re: Effective uses of c `goto' statement foo <opaquefoo@gmail.com> - 2020-12-02 11:03 -0800
Re: Effective uses of c `goto' statement David Brown <david.brown@hesbynett.no> - 2020-12-02 21:02 +0100
Re: Effective uses of c `goto' statement Öö Tiib <ootiib@hot.ee> - 2020-12-05 03:04 -0800
Re: Effective uses of c `goto' statement Öö Tiib <ootiib@hot.ee> - 2020-12-05 03:36 -0800
Good thing this isn't a Python group (Was: Effective uses of c `goto' statement) gazelle@shell.xmission.com (Kenny McCormack) - 2020-12-05 11:45 +0000
Re: Good thing this isn't a Python group (Was: Effective uses of c `goto' statement) David Brown <david.brown@hesbynett.no> - 2020-12-05 14:38 +0100
Re: Good thing this isn't a Python group (Was: Effective uses of c `goto' statement) Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-12-06 11:00 +0000
Re: Good thing this isn't a Python group (Was: Effective uses of c `goto' statement) gazelle@shell.xmission.com (Kenny McCormack) - 2020-12-06 12:33 +0000
Re: Good thing this isn't a Python group Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-12-06 14:09 -0800
Re: Good thing this isn't a Python group Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-12-08 21:01 +0000
Re: Effective uses of c `goto' statement David Brown <david.brown@hesbynett.no> - 2020-12-05 14:37 +0100
Re: Effective uses of c `goto' statement Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-02 20:07 +0000
Re: Effective uses of c `goto' statement Bonita Montero <Bonita.Montero@gmail.com> - 2020-12-03 17:10 +0100
Re: Effective uses of c `goto' statement "jfbod...@gmail.com" <jfbode1029@gmail.com> - 2020-12-03 15:40 -0800
Re: Effective uses of c `goto' statement Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-03 16:14 -0800
Re: Effective uses of c `goto' statement kevin shell <kevin@fedora.osfans.org> - 2020-12-04 16:29 +0800
Re: Effective uses of c `goto' statement "jfbod...@gmail.com" <jfbode1029@gmail.com> - 2020-12-04 07:09 -0800
Re: Effective uses of c `goto' statement "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2020-12-04 10:14 -0800
Re: Effective uses of c `goto' statement Bart <bc@freeuk.com> - 2020-12-04 11:19 +0000
Re: Effective uses of c `goto' statement Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-04 04:35 -0800
Re: Effective uses of c `goto' statement Bart <bc@freeuk.com> - 2020-12-04 13:50 +0000
Re: Effective uses of c `goto' statement Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-12-04 10:49 -0800
Re: Effective uses of c `goto' statement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-04 13:09 +0000
Re: Effective uses of c `goto' statement Bart <bc@freeuk.com> - 2020-12-04 14:03 +0000
Re: Effective uses of c `goto' statement Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-03 23:02 -0800
Re: Effective uses of c `goto' statement Bonita Montero <Bonita.Montero@gmail.com> - 2020-12-04 19:38 +0100
Re: Effective uses of c `goto' statement Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-05 01:29 -0800
Re: Effective uses of c `goto' statement kegs@provalid.com (Kent Dickey) - 2020-12-09 00:23 -0600
Re: Effective uses of c `goto' statement Bart <bc@freeuk.com> - 2020-12-09 12:39 +0000
Re: Effective uses of c `goto' statement Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-10 10:45 -0800
Re: Effective uses of c `goto' statement Bonita Montero <Bonita.Montero@gmail.com> - 2020-12-04 19:35 +0100
Re: Effective uses of c `goto' statement Richard Damon <Richard@Damon-Family.org> - 2020-12-04 19:49 -0500
Re: Effective uses of c `goto' statement Richard Damon <Richard@Damon-Family.org> - 2020-12-04 20:52 -0500
Re: Effective uses of c `goto' statement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-05 02:19 +0000
Re: Effective uses of c `goto' statement Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-05 01:43 -0800
Re: Effective uses of c `goto' statement "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-12-05 02:00 -0800
Re: Effective uses of c `goto' statement "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-12-05 02:01 -0800
Re: Effective uses of c `goto' statement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-05 22:45 +0000
Re: Effective uses of c `goto' statement "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-12-11 19:33 -0800
Re: Effective uses of c `goto' statement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-12 21:12 +0000
Re: Effective uses of c `goto' statement Bart <bc@freeuk.com> - 2020-12-05 12:49 +0000
Re: Effective uses of c `goto' statement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-05 22:42 +0000
Re: Effective uses of c `goto' statement Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-06 05:46 -0800
Re: Effective uses of c `goto' statement Bart <bc@freeuk.com> - 2020-12-06 14:16 +0000
Re: Effective uses of c `goto' statement Öö Tiib <ootiib@hot.ee> - 2020-12-06 06:54 -0800
Re: Effective uses of c `goto' statement Bart <bc@freeuk.com> - 2020-12-06 16:19 +0000
Re: Effective uses of c `goto' statement Öö Tiib <ootiib@hot.ee> - 2020-12-06 15:34 -0800
Re: Effective uses of c `goto' statement Bart <bc@freeuk.com> - 2020-12-06 23:56 +0000
Re: Effective uses of c `goto' statement David Brown <david.brown@hesbynett.no> - 2020-12-07 11:11 +0100
Re: Effective uses of c `goto' statement Bart <bc@freeuk.com> - 2020-12-07 11:41 +0000
Re: Effective uses of c `goto' statement David Brown <david.brown@hesbynett.no> - 2020-12-07 15:35 +0100
Re: Effective uses of c `goto' statement Bart <bc@freeuk.com> - 2020-12-07 15:48 +0000
Re: Effective uses of c `goto' statement Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-12-07 11:46 -0800
Re: Effective uses of c `goto' statement Bart <bc@freeuk.com> - 2020-12-07 20:01 +0000
Re: Effective uses of c `goto' statement Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-12-07 13:03 -0800
Re: Effective uses of c `goto' statement David Brown <david.brown@hesbynett.no> - 2020-12-07 11:01 +0100
Re: Effective uses of c `goto' statement Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-07 03:35 -0800
Re: Effective uses of c `goto' statement Richard Damon <Richard@Damon-Family.org> - 2020-12-07 07:33 -0500
Re: Effective uses of c `goto' statement gazelle@shell.xmission.com (Kenny McCormack) - 2020-12-07 13:11 +0000
Re: Effective uses of c `goto' statement Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-07 05:24 -0800
Re: Effective uses of c `goto' statement Richard Damon <Richard@Damon-Family.org> - 2020-12-07 08:58 -0500
Re: Effective uses of c `goto' statement David Brown <david.brown@hesbynett.no> - 2020-12-07 15:48 +0100
Re: Effective uses of c `goto' statement David Brown <david.brown@hesbynett.no> - 2020-12-07 15:45 +0100
Re: Effective uses of c `goto' statement Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2020-12-07 07:29 -0800
Re: Effective uses of c `goto' statement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-07 22:34 +0000
Re: Effective uses of c `goto' statement David Brown <david.brown@hesbynett.no> - 2020-12-07 15:38 +0100
Re: Effective uses of c `goto' statement kegs@provalid.com (Kent Dickey) - 2020-12-10 15:45 -0600
Re: Effective uses of c `goto' statement Vir Campestris <vir.campestris@invalid.invalid> - 2020-12-07 21:43 +0000
Re: Effective uses of c `goto' statement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-07 23:02 +0000
Re: Effective uses of c `goto' statement Vir Campestris <vir.campestris@invalid.invalid> - 2020-12-10 21:15 +0000
Re: Effective uses of c `goto' statement Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-12-10 22:48 +0000
Re: Effective uses of c `goto' statement Vir Campestris <vir.campestris@invalid.invalid> - 2020-12-11 20:59 +0000
Re: Effective uses of c `goto' statement Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-12-11 14:07 -0800
Re: Effective uses of c `goto' statement Bonita Montero <Bonita.Montero@gmail.com> - 2020-12-05 08:55 +0100
Re: Effective uses of c `goto' statement Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-12-05 02:04 -0800
Re: Effective uses of c `goto' statement Vir Campestris <vir.campestris@invalid.invalid> - 2020-12-07 21:37 +0000
Re: Effective uses of c `goto' statement James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-12-07 17:03 -0500
Re: Effective uses of c `goto' statement David Brown <david.brown@hesbynett.no> - 2020-12-07 23:17 +0100
Re: Effective uses of c `goto' statement Kaz Kylheku <563-365-8930@kylheku.com> - 2020-12-07 22:19 +0000
Re: Effective uses of c `goto' statement Vir Campestris <vir.campestris@invalid.invalid> - 2020-12-10 21:13 +0000
Re: Effective uses of c `goto' statement kegs@provalid.com (Kent Dickey) - 2020-12-10 15:30 -0600
Re: Effective uses of c `goto' statement "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2020-12-05 13:01 -0500
Re: Effective uses of c `goto' statement luser droog <luser.droog@gmail.com> - 2020-12-11 19:27 -0800
Page 5 of 6 — ← Prev page 1 2 3 4 [5] 6 Next page →
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2020-12-07 11:41 +0000 |
| Message-ID | <7yozH.96593$L_49.11237@fx22.ams4> |
| In reply to | #157016 |
On 07/12/2020 10:11, David Brown wrote:
> On 07/12/2020 00:56, Bart wrote:
>> Yes, no, maybe! This is the usual story with C:
>
> Eh, no. "I don't understand C, but like to exaggerate and spread FUD!"
> - this is the usual story with Bart.
>
> The rules are simple. People might use the language in unclear ways,
> but the language itself is clear. Macros are simple text substitution.
>
>>
>> * Macros may evaluate their arguments twice, problematic if that causes
>> extra side-efects.
>
> This isn't news to anyone who has the slightest understanding and
> experience of the language. And it is not hard to handle. Sometimes it
> is an inconvenience - no language is ideal in all cases. (And no
> language - including yours - protects users from bad programmers who
> write confusing code.)
>
>>
>> * You can create type-specific versions, with a local temporary, but you
>> lose the advantage of being type-agnostic
>>
>
> That would be inline functions, not function-like macros. (Unless you
> are allowing gcc extensions, in which case other extensions solve all
> your problems here.) And yes, that's a limitation of C. It's not
> unclear, or confusing, or mixed-up - it's just a limitation of the language.
>
>> * You can implement it via a function, but it may or may not inline it,
>> or if it is extern, LTO may not be available to inline it.
>
> The compiler will inline it if it makes a difference to the speed. (If
> the compiler can't inline such simple functions, you are probably using
> the wrong compiler - certainly you are not going to get efficient object
> code no matter what you write.)
>
>>
>> * Even inside a function,
(I meant inside the same module)
it you to use with int arguments, it may end
>> up doing a floating point operation. (gcc-O3 does so even with the
>> function local.)
>
> I can't make sense of what you are trying to say here. Post an example
> that can be pasted into <https://godbolt.org>, and I will have a look.
Try:
--------------------------------
#include <stdio.h>
#include <stdlib.h>
double square(double x) {
return x*x;
}
int main(void) {
volatile int a=rand(),b;
b=square(a);
}
--------------------------------
On godbolt with gcc for x64, version 10.1, -O3, it will perform that
squaring using floating point code.
The intention is to have a 'square' feature in the language that
multiples its argument with itself. But I'd prefer one that works with
both ints and floats (and both kinds of floats).
This will work with ints, but less efficiently, and with sometimes
different results using int64. It will also work with floats, but
surprisingly even less efficiently:
----------------------------------------
double square(double x) {
return x*x;
}
int main(void) {
volatile float a=rand(),b;
for (int i=0; i<1000000000; ++i) {
b=square(a);
}
}
----------------------------------------
On my machine (gcc 8.1.0, -O2 or -O3) this took 3 times as long using
floats as doubles. And this is with everything visible to the compiler.
>>
>> So, nothing is really guaranteed.
>>
>
> When you refuse to understand anything, and prefer to invent new ways to
> get things wrong or confuse yourself, then you are right - for /you/,
> nothing is guaranteed. Other C programmers don't have the same issues.
I think that was a pretty good summary. You have to choose between
macros, or typed functions, or inline functions, you have to choose the
right compiler, the right options, you might have to depend on link-time
optimisations, you might use non-standard features of some compilers, or
you choose C++ and all the problems magically go away.
It's the same 'story'.
(My languages have some of the same problems and lack many of the
possibilities such as inline functions.
However, for basic functionality such as 'square' and 'pow' (also abs,
min, max....), I have these as built-in operations 'sqr' and '**',
overloaded for ints, float32 and float64.)
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2020-12-07 15:35 +0100 |
| Message-ID | <rqlej1$dmb$1@dont-email.me> |
| In reply to | #157019 |
On 07/12/2020 12:41, Bart wrote:
> On 07/12/2020 10:11, David Brown wrote:
>> On 07/12/2020 00:56, Bart wrote:
>
>
> it you to use with int arguments, it may end
>>> up doing a floating point operation. (gcc-O3 does so even with the
>>> function local.)
>>
>> I can't make sense of what you are trying to say here. Post an example
>> that can be pasted into <https://godbolt.org>, and I will have a look.
>
> Try:
> --------------------------------
>
> #include <stdio.h>
> #include <stdlib.h>
>
> double square(double x) {
> return x*x;
> }
>
> int main(void) {
> volatile int a=rand(),b;
>
> b=square(a);
> }
> --------------------------------
>
> On godbolt with gcc for x64, version 10.1, -O3, it will perform that
> squaring using floating point code.
>
Of course it will. Floating point can have different effects and can
give sometimes different results with regard to rounding, overflow,
floating point exception flags, etc.
> The intention is to have a 'square' feature in the language that
> multiples its argument with itself. But I'd prefer one that works with
> both ints and floats (and both kinds of floats).
>
I appreciate that (and agree with it). C doesn't have a way to achieve
this without some compromises (though there are different options with
different pros and cons).
Having "square" built into the language would not be a useful solution.
> This will work with ints, but less efficiently, and with sometimes
> different results using int64. It will also work with floats, but
> surprisingly even less efficiently:
>
> ----------------------------------------
> double square(double x) {
> return x*x;
> }
>
> int main(void) {
> volatile float a=rand(),b;
>
> for (int i=0; i<1000000000; ++i) {
> b=square(a);
> }
> }
> ----------------------------------------
>
> On my machine (gcc 8.1.0, -O2 or -O3) this took 3 times as long using
> floats as doubles. And this is with everything visible to the compiler.
>
Again, the compiler is only doing what it is asked to do. First you are
converting from an integer to a float, which might have different
effects (in particular, most 32-bit integer values cannot be represented
exactly as 32-bit floating point), then you are converting it to double,
then you are squaring it, then converting the result back to float.
These may all have effects that are hard to predict for a compiler.
>>>
>>> So, nothing is really guaranteed.
>>>
>>
>> When you refuse to understand anything, and prefer to invent new ways to
>> get things wrong or confuse yourself, then you are right - for /you/,
>> nothing is guaranteed. Other C programmers don't have the same issues.
>
> I think that was a pretty good summary. You have to choose between
> macros, or typed functions, or inline functions, you have to choose the
> right compiler, the right options, you might have to depend on link-time
> optimisations, you might use non-standard features of some compilers, or
> you choose C++ and all the problems magically go away.
>
> It's the same 'story'.
C doesn't have an ideal solution to this kind of task, so you have to
have a compromise in some way. That's fine - there is no disagreement
there. My disagreement is about your suggestions that it is unclear, or
mixed-up, or without guarantees. /That/ is where you are wrong -
knowingly, intentionally and unhelpfully wrong.
>
> (My languages have some of the same problems and lack many of the
> possibilities such as inline functions.
>
> However, for basic functionality such as 'square' and 'pow' (also abs,
> min, max....), I have these as built-in operations 'sqr' and '**',
> overloaded for ints, float32 and float64.)
>
Squaring is not "basic functionality" IMHO - though "pow", "abs", "min"
and "max" are. It is not a good idea to have more built-in functions in
a language than are useful - they take up identifier space, add little
useful, and mean users have to keep looking up details in manuals if
they want to take advantage of such rarely used functions. It's simpler
for a programmer to write "x * x" or "x ** 2" than "square(x)", making
it a pointless feature.
What would make a lot more sense is to add features to the language that
allow programmers to make their own multi-type functions (if you don't
already have such features), so that they could make a "square" function
with the convenience and efficiency of a built-in function.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2020-12-07 15:48 +0000 |
| Message-ID | <29szH.583671$ckra.425901@fx37.ams4> |
| In reply to | #157033 |
On 07/12/2020 14:35, David Brown wrote:
> On 07/12/2020 12:41, Bart wrote:
>> ----------------------------------------
>> double square(double x) {
>> return x*x;
>> }
>>
>> int main(void) {
>> volatile float a=rand(),b;
>>
>> for (int i=0; i<1000000000; ++i) {
>> b=square(a);
>> }
>> }
>> ----------------------------------------
>>
>> On my machine (gcc 8.1.0, -O2 or -O3) this took 3 times as long using
>> floats as doubles. And this is with everything visible to the compiler.
>>
>
> Again, the compiler is only doing what it is asked to do. First you are
> converting from an integer to a float, which might have different
> effects (in particular, most 32-bit integer values cannot be represented
> exactly as 32-bit floating point), then you are converting it to double,
> then you are squaring it, then converting the result back to float.
> These may all have effects that are hard to predict for a compiler.
This example does float -> double -> float. That conversion appears to
take time. A dedicated square-float would take the same time as
square-double.
>> However, for basic functionality such as 'square' and 'pow' (also abs,
>> min, max....), I have these as built-in operations 'sqr' and '**',
>> overloaded for ints, float32 and float64.)
>>
>
> Squaring is not "basic functionality" IMHO - though "pow", "abs", "min"
> and "max" are.
I added 'sqr' because it was in Pascal IIRC. So Wirth decided it was
useful having as a basic feature.
(It is also useful in bytecode because you can do
'Push X; Sqr' instead of 'Push X; Push X [or Dupl]; Mul', the latter
also requiring double-type dispatch instead of single.)
It is not a good idea to have more built-in functions in
> a language than are useful - they take up identifier space, add little
> useful, and mean users have to keep looking up details in manuals if
> they want to take advantage of such rarely used functions.
Have a look at the docs of the standard container types of C++.
> What would make a lot more sense is to add features to the language that
> allow programmers to make their own multi-type functions (if you don't
> already have such features), so that they could make a "square" function
> with the convenience and efficiency of a built-in function.
Yes, I saw your attempt to use the _Generic feature of C to create an
overloaded 'square' function. That was starting to look like the inside
of a compiler. You shouldn't expect application programmers to have to
extend their own implementations! Plus each one will do it differently
or concentrate on different aspects.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2020-12-07 11:46 -0800 |
| Message-ID | <878sa9flh2.fsf@nosuchdomain.example.com> |
| In reply to | #157019 |
Bart <bc@freeuk.com> writes:
> On 07/12/2020 10:11, David Brown wrote:
>> On 07/12/2020 00:56, Bart wrote:
>>> Yes, no, maybe! This is the usual story with C:
>>
>> Eh, no. "I don't understand C, but like to exaggerate and spread FUD!"
>> - this is the usual story with Bart.
>>
>> The rules are simple. People might use the language in unclear ways,
>> but the language itself is clear. Macros are simple text substitution.
>>
>>>
>>> * Macros may evaluate their arguments twice, problematic if that causes
>>> extra side-efects.
>>
>> This isn't news to anyone who has the slightest understanding and
>> experience of the language. And it is not hard to handle. Sometimes it
>> is an inconvenience - no language is ideal in all cases. (And no
>> language - including yours - protects users from bad programmers who
>> write confusing code.)
>>
>>>
>>> * You can create type-specific versions, with a local temporary, but you
>>> lose the advantage of being type-agnostic
>>>
>>
>> That would be inline functions, not function-like macros. (Unless you
>> are allowing gcc extensions, in which case other extensions solve all
>> your problems here.) And yes, that's a limitation of C. It's not
>> unclear, or confusing, or mixed-up - it's just a limitation of the language.
>>
>>> * You can implement it via a function, but it may or may not inline it,
>>> or if it is extern, LTO may not be available to inline it.
>>
>> The compiler will inline it if it makes a difference to the speed. (If
>> the compiler can't inline such simple functions, you are probably using
>> the wrong compiler - certainly you are not going to get efficient object
>> code no matter what you write.)
>>
>>>
>>> * Even inside a function,
>
> (I meant inside the same module)
What is a "module"? C has no such construct. Do you mean a translation
unit?
>>> it you to use with int arguments, it may end
>>> up doing a floating point operation. (gcc-O3 does so even with the
>>> function local.)
>>
>> I can't make sense of what you are trying to say here. Post an example
>> that can be pasted into <https://godbolt.org>, and I will have a look.
>
> Try:
> --------------------------------
>
> #include <stdio.h>
> #include <stdlib.h>
>
> double square(double x) {
> return x*x;
> }
>
> int main(void) {
> volatile int a=rand(),b;
>
> b=square(a);
> }
> --------------------------------
>
> On godbolt with gcc for x64, version 10.1, -O3, it will perform that
> squaring using floating point code.
You wrote a function that takes a double argument, performs a double
multiplication, and returns a double result, and you're suprised that it
does a floating-point operation? Seriously?
We all understand that C's support for type-generic operations is not
strong.
> The intention is to have a 'square' feature in the language that
> multiples its argument with itself. But I'd prefer one that works with
> both ints and floats (and both kinds of floats).
There is only one kind of float. There are three floating-point types:
float, double, and long double.
You can't directly do what you want in C. You can in some other
languages (for example, a C++ template would be straightfoward).
I see no point in complaining about that fact again and again
and again.
[...]
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2020-12-07 20:01 +0000 |
| Message-ID | <qSvzH.294470$b5kb.236477@fx15.ams4> |
| In reply to | #157043 |
On 07/12/2020 19:46, Keith Thompson wrote: > Bart <bc@freeuk.com> writes: >> (I meant inside the same module) > > What is a "module"? Seriously? >> On godbolt with gcc for x64, version 10.1, -O3, it will perform that >> squaring using floating point code. > > You wrote a function that takes a double argument, performs a double > multiplication, and returns a double result, and you're suprised that it > does a floating-point operation? Seriously? Why not? I'm not up with all the possible optimisations of gcc and clang. If the results will be the same (especially if the possibility of overflow is ignored, a favourite of such compilers), why not eliminate that expensive conversion? My example was supposed to show the disadvantage of a function-based solution. (Remember that was just an example of trivial code being made into a tiny function. But since that trivial code may operate on i32, u64, f32, f64, the solution is not so straightforward) > We all understand that C's support for type-generic operations is not > strong. > >> The intention is to have a 'square' feature in the language that >> multiples its argument with itself. But I'd prefer one that works with >> both ints and floats (and both kinds of floats). > > There is only one kind of float. There are three floating-point types: > float, double, and long double. > > You can't directly do what you want in C. You can in some other > languages (for example, a C++ template would be straightfoward). > I see no point in complaining about that fact again and again > and again. This was about (if you read back far enough) justifying the use of 'goto' for code-sharing within a function, with one possible alternative being to put the common code into small functions. Both are possible in C, including the goto that I would prefer. What is not possible are alternative featuress that eliminate the goto, but keep the code within the function, and without having to invent an interface to it.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2020-12-07 13:03 -0800 |
| Message-ID | <87v9dde3bz.fsf@nosuchdomain.example.com> |
| In reply to | #157044 |
Bart <bc@freeuk.com> writes:
> On 07/12/2020 19:46, Keith Thompson wrote:
>> Bart <bc@freeuk.com> writes:
>
>>> (I meant inside the same module)
>>
>> What is a "module"?
>
> Seriously?
Yes, seriously. Some languages have constructs they call "modules".
C does not.
What do *you* mean when you use the word "module" in the context
of C? I could guess that you're referring to what C calls a
"translation unit", but I don't want to guess. If you mean
"translation unit", you could just say so.
>>> On godbolt with gcc for x64, version 10.1, -O3, it will perform that
>>> squaring using floating point code.
>>
>> You wrote a function that takes a double argument, performs a double
>> multiplication, and returns a double result, and you're suprised that it
>> does a floating-point operation? Seriously?
>
> Why not? I'm not up with all the possible optimisations of gcc and
> clang. If the results will be the same (especially if the possibility
> of overflow is ignored, a favourite of such compilers), why not
> eliminate that expensive conversion?
Because you wrote code that performs a floating-point operation, and
because floating-point and integer operations have different semantics.
It *might* be possible to perform the optimization you suggest, but I
wouldn't expect a compiler to do so (and there could well be corner
cases I haven't thought of where the optimization would be semantically
invalid).
> My example was supposed to show the disadvantage of a function-based
> solution.
Something that we're all aware of, but you insist on pretending that
it's far more complicated than it really is.
[...]
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2020-12-07 11:01 +0100 |
| Message-ID | <rqkui4$pc9$1@dont-email.me> |
| In reply to | #156999 |
On 07/12/2020 00:34, Öö Tiib wrote:
> On Sunday, 6 December 2020 at 18:19:46 UTC+2, Bart wrote:
>> On 06/12/2020 14:54, Öö Tiib wrote:
>>> On Sunday, 6 December 2020 at 16:17:07 UTC+2, Bart wrote:
>>
>>>> But lots of tiny functions created for no good reason comes close.
>>>
>>> Said function was perhaps made for one can write "square(a - b)"
>>> instead of "(a - b) * (a - b)". What is so criminal about it?
>>> How it annoys you?
>> Did you read my post? I listed reasons for creating small functions, and
>> reasons for not creating them.
>
> Yes I did. As answer to example of that square(x) you did tell how
> you hate files and directories the most and then that such short
> functions come close. It wasn't transparent to me that you did
> talk about some other kind of functions than to what you were
> replying and whose examples no one brought, sorry.
>
>> Creating a mathematical function such as square would probably go into
>> the first list. Partly because it would not be relevant to that one
>> function where it is used.
>>
>> (However, in C that specific one would probably be better off as a
>> macro. Such functions I would prefer to be properly overloaded, and not
>> have the possible extra overheads of a function call either.
>
> Wouldn't such macro square(foo(x)) call foo(x) twice?
Yes, assuming he was thinking of a simple macro:
#define square(x) ((x) * (x))
Generally, "static inline" functions (though opinions seem to vary about
the "static" part) are a better choice than function-like macros than
macros. One of the reasons for that is that the arguments are only
evaluated once, regardless of the function definition.
However, I am guessing that Bart thinks a macro is good here because it
will adapt to the type, while a function will convert to the type of the
parameter. That's a valid point, and there are perhaps 4 different
solutions, each with their pros and cons:
1. Use a macro with the name in all-caps, making it clear to users that
it is a macro and you can expect funny things to be done such as
multiple evaluation of the arguments.
2. Give up on portability, and use gcc extensions that work well for
this kind of thing:
#define square2(x) ({const __typeof(x) y = x; y * y;})
or
#define square3(x) ({const __auto_type y = x; y * y;})
(It would be very nice if these extensions were added to standard C.)
3. Use C11 _Generic:
int square_int(int x) { return x * x; }
long square_long(long x) { return x * x; }
double square_double(double x) { return x * x; }
#define square4(x) _Generic((x), \
int : square_int, \
long : square_long, \
double : square_double \
)(x)
This works - but it's a bit ugly and repetitive, and requires listing
all types that you might want when you define the macro.
4. Give up on C and use C++ :
template<typename T> T square(T x) { return x * x; }
> That can
> lose in efficiency or even cause hard to notice defects
> when that foo has side effects. Meanwhile modern compilers
> tend to inline such short functions. The gcc does it even link time
> with -flto option.
>
>> In my languages, 'sqr' is an overloaded operator.)
>
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2020-12-07 03:35 -0800 |
| Message-ID | <dd346223-2efa-4513-9ed8-220f29c9449fn@googlegroups.com> |
| In reply to | #157015 |
On Monday, 7 December 2020 at 10:01:58 UTC, David Brown wrote:
>
> 2. Give up on portability, and use gcc extensions that work well for
> this kind of thing:
>
> #define square2(x) ({const __typeof(x) y = x; y * y;})
>
> or
>
> #define square3(x) ({const __auto_type y = x; y * y;})
>
> (It would be very nice if these extensions were added to standard C.)
>
Are you sure these work?
It looks to me (not being familar with the extension) that this means
"create a block in which you calculate the result of y * y and discard".
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2020-12-07 07:33 -0500 |
| Message-ID | <BipzH.222927$J92.164410@fx48.iad> |
| In reply to | #157018 |
On 12/7/20 6:35 AM, Malcolm McLean wrote:
> On Monday, 7 December 2020 at 10:01:58 UTC, David Brown wrote:
>>
>> 2. Give up on portability, and use gcc extensions that work well for
>> this kind of thing:
>>
>> #define square2(x) ({const __typeof(x) y = x; y * y;})
>>
>> or
>>
>> #define square3(x) ({const __auto_type y = x; y * y;})
>>
>> (It would be very nice if these extensions were added to standard C.)
>>
> Are you sure these work?
>
> It looks to me (not being familar with the extension) that this means
> "create a block in which you calculate the result of y * y and discard".
>
It is using the GCC extension that basically says if you have squiggly
braces inside round braces, the value of last statement inside the
squiggly braces becomes the value of the expression inside the round braces.
Note, in standard C, it would be a syntax error to have the squiggly
braces there.
[toc] | [prev] | [next] | [standalone]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2020-12-07 13:11 +0000 |
| Message-ID | <rql9mv$3ps9q$1@news.xmission.com> |
| In reply to | #157022 |
In article <BipzH.222927$J92.164410@fx48.iad>,
Richard Damon <Richard@Damon-Family.org> wrote:
...
>It is using the GCC extension that basically says if you have squiggly
>braces inside round braces, the value of last statement inside the
>squiggly braces becomes the value of the expression inside the round braces.
Or you could just Google for "statement expression".
--
"Everything Roy (aka, AU8YOG) touches turns to crap."
--citizens of alt.obituaries--
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2020-12-07 05:24 -0800 |
| Message-ID | <4f180506-503c-4527-b039-e55d55ed1f2an@googlegroups.com> |
| In reply to | #157022 |
On Monday, 7 December 2020 at 12:33:54 UTC, Richard Damon wrote:
> On 12/7/20 6:35 AM, Malcolm McLean wrote:
> > On Monday, 7 December 2020 at 10:01:58 UTC, David Brown wrote:
> >>
> >> 2. Give up on portability, and use gcc extensions that work well for
> >> this kind of thing:
> >>
> >> #define square2(x) ({const __typeof(x) y = x; y * y;})
> >>
> >> or
> >>
> >> #define square3(x) ({const __auto_type y = x; y * y;})
> >>
> >> (It would be very nice if these extensions were added to standard C.)
> >>
> > Are you sure these work?
> >
> > It looks to me (not being familar with the extension) that this means
> > "create a block in which you calculate the result of y * y and discard".
> >
> It is using the GCC extension that basically says if you have squiggly
> braces inside round braces, the value of last statement inside the
> squiggly braces becomes the value of the expression inside the round braces.
>
> Note, in standard C, it would be a syntax error to have the squiggly
> braces there.
>
So in fact from a structured programming perspective, it would be best to
implement all functions as macros. Then each block has a single point of
entry and a single point of exit.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2020-12-07 08:58 -0500 |
| Message-ID | <yyqzH.66966$NL3.58243@fx12.iad> |
| In reply to | #157027 |
On 12/7/20 8:24 AM, Malcolm McLean wrote:
> On Monday, 7 December 2020 at 12:33:54 UTC, Richard Damon wrote:
>> On 12/7/20 6:35 AM, Malcolm McLean wrote:
>>> On Monday, 7 December 2020 at 10:01:58 UTC, David Brown wrote:
>>>>
>>>> 2. Give up on portability, and use gcc extensions that work well for
>>>> this kind of thing:
>>>>
>>>> #define square2(x) ({const __typeof(x) y = x; y * y;})
>>>>
>>>> or
>>>>
>>>> #define square3(x) ({const __auto_type y = x; y * y;})
>>>>
>>>> (It would be very nice if these extensions were added to standard C.)
>>>>
>>> Are you sure these work?
>>>
>>> It looks to me (not being familar with the extension) that this means
>>> "create a block in which you calculate the result of y * y and discard".
>>>
>> It is using the GCC extension that basically says if you have squiggly
>> braces inside round braces, the value of last statement inside the
>> squiggly braces becomes the value of the expression inside the round braces.
>>
>> Note, in standard C, it would be a syntax error to have the squiggly
>> braces there.
>>
> So in fact from a structured programming perspective, it would be best to
> implement all functions as macros. Then each block has a single point of
> entry and a single point of exit.
>
Never said that, but macros do provide an easy way to make a 'type
generic' function in C. And the block extension provides a handy way to
do more with this and get around the multiple evaluation of the
expression issue.
In C++, this would be a template. C probably doesn't want to go that far
(who wants a Turing complete language in a single feature within your
Turing Complete language), but can get a large part of the benefit with
a few small tweeks.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2020-12-07 15:48 +0100 |
| Message-ID | <rqlfc2$j9g$1@dont-email.me> |
| In reply to | #157030 |
On 07/12/2020 14:58, Richard Damon wrote:
> On 12/7/20 8:24 AM, Malcolm McLean wrote:
>> On Monday, 7 December 2020 at 12:33:54 UTC, Richard Damon wrote:
>>> On 12/7/20 6:35 AM, Malcolm McLean wrote:
>>>> On Monday, 7 December 2020 at 10:01:58 UTC, David Brown wrote:
>>>>>
>>>>> 2. Give up on portability, and use gcc extensions that work well for
>>>>> this kind of thing:
>>>>>
>>>>> #define square2(x) ({const __typeof(x) y = x; y * y;})
>>>>>
>>>>> or
>>>>>
>>>>> #define square3(x) ({const __auto_type y = x; y * y;})
>>>>>
>>>>> (It would be very nice if these extensions were added to standard C.)
>>>>>
>>>> Are you sure these work?
>>>>
>>>> It looks to me (not being familar with the extension) that this means
>>>> "create a block in which you calculate the result of y * y and discard".
>>>>
>>> It is using the GCC extension that basically says if you have squiggly
>>> braces inside round braces, the value of last statement inside the
>>> squiggly braces becomes the value of the expression inside the round braces.
>>>
>>> Note, in standard C, it would be a syntax error to have the squiggly
>>> braces there.
>>>
>> So in fact from a structured programming perspective, it would be best to
>> implement all functions as macros. Then each block has a single point of
>> entry and a single point of exit.
>>
>
> Never said that, but macros do provide an easy way to make a 'type
> generic' function in C. And the block extension provides a handy way to
> do more with this and get around the multiple evaluation of the
> expression issue.
>
> In C++, this would be a template. C probably doesn't want to go that far
> (who wants a Turing complete language in a single feature within your
> Turing Complete language), but can get a large part of the benefit with
> a few small tweeks.
>
Yes.
Given that statement expressions have been available in gcc for a very
long time (decades, I think), and presumably also clang, they seem
reasonable candidates for including in future C standards. The same
applies to "typeof". They make this type of macro a lot more flexible,
and far easier to write and use than _Generic.
Templates would mean adding overloads and name mangling to the language,
and that is, IMHO, a few too many big steps for C.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2020-12-07 15:45 +0100 |
| Message-ID | <rqlf6b$i1r$1@dont-email.me> |
| In reply to | #157027 |
On 07/12/2020 14:24, Malcolm McLean wrote:
> On Monday, 7 December 2020 at 12:33:54 UTC, Richard Damon wrote:
>> On 12/7/20 6:35 AM, Malcolm McLean wrote:
>>> On Monday, 7 December 2020 at 10:01:58 UTC, David Brown wrote:
>>>>
>>>> 2. Give up on portability, and use gcc extensions that work well for
>>>> this kind of thing:
>>>>
>>>> #define square2(x) ({const __typeof(x) y = x; y * y;})
>>>>
>>>> or
>>>>
>>>> #define square3(x) ({const __auto_type y = x; y * y;})
>>>>
>>>> (It would be very nice if these extensions were added to standard C.)
>>>>
>>> Are you sure these work?
>>>
>>> It looks to me (not being familar with the extension) that this means
>>> "create a block in which you calculate the result of y * y and discard".
>>>
>> It is using the GCC extension that basically says if you have squiggly
>> braces inside round braces, the value of last statement inside the
>> squiggly braces becomes the value of the expression inside the round braces.
>>
>> Note, in standard C, it would be a syntax error to have the squiggly
>> braces there.
>>
> So in fact from a structured programming perspective, it would be best to
> implement all functions as macros. Then each block has a single point of
> entry and a single point of exit.
>
I can't imagine how you came to that conclusion. No, it would not be
"best" (in any sense) to implement all functions as macros. No,
implementing them as macros would not ensure that each block has a
single point of entry and exit. No, code is not strictly "more
structured" by restricting entry and exit to single points. No, code is
not necessarily better for being "more structured".
In several programming languages, the value of a function is the value
of the final statement or expression in the function. Maybe that is
what you are thinking of.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2020-12-07 07:29 -0800 |
| Message-ID | <5d813707-88cb-4279-9f6b-8afc3d025886n@googlegroups.com> |
| In reply to | #157035 |
On Monday, 7 December 2020 at 14:45:48 UTC, David Brown wrote: > On 07/12/2020 14:24, Malcolm McLean wrote: > > > So in fact from a structured programming perspective, it would be best to > > implement all functions as macros. Then each block has a single point of > > entry and a single point of exit. > > > I can't imagine how you came to that conclusion. No, it would not be > "best" (in any sense) to implement all functions as macros. No, > implementing them as macros would not ensure that each block has a > single point of entry and exit. No, code is not strictly "more > structured" by restricting entry and exit to single points. No, code is > not necessarily better for being "more structured". > That's a central rule. Each block of a structured program has a single point of entry and a single point of exit. There's a general consensus that structured programming works well. But it's not the only paradigm for organising code.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2020-12-07 22:34 +0000 |
| Message-ID | <87wnxtmejn.fsf@bsb.me.uk> |
| In reply to | #157022 |
Just picking a point to make this remark... Richard Damon <Richard@Damon-Family.org> writes: > It is using the GCC extension that basically says if you have squiggly > braces inside round braces, the value of last statement inside the > squiggly braces becomes the value of the expression inside the round > braces. BCPL (ah, those were the days!) had an expression form VALOF <block> where the block of statements should include at least one RESULTIS <expression> statement. Given the influence of BCPL on C, I wonder if this was ever considered for C. Probably not, because C lost the distinction between functions and routines (as BCPL calls them). In K&R C, all functions "return" something (this was before void) whereas BCPL had LET f(a, b, ... c) = <expression> for functions and LET r(a, b, ... c) BE <block> for routines. For anything but the simplest functions, the defining expression would be a VALOF $( ... RESULTIS E ... $) expression. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2020-12-07 15:38 +0100 |
| Message-ID | <rqleok$dmb$2@dont-email.me> |
| In reply to | #157018 |
On 07/12/2020 12:35, Malcolm McLean wrote:
> On Monday, 7 December 2020 at 10:01:58 UTC, David Brown wrote:
>>
>> 2. Give up on portability, and use gcc extensions that work well for
>> this kind of thing:
>>
>> #define square2(x) ({const __typeof(x) y = x; y * y;})
>>
>> or
>>
>> #define square3(x) ({const __auto_type y = x; y * y;})
>>
>> (It would be very nice if these extensions were added to standard C.)
>>
> Are you sure these work?
>
> It looks to me (not being familar with the extension) that this means
> "create a block in which you calculate the result of y * y and discard".
>
Yes, I am sure they work - as I /am/ familiar with the extension.
<https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html>
[toc] | [prev] | [next] | [standalone]
| From | kegs@provalid.com (Kent Dickey) |
|---|---|
| Date | 2020-12-10 15:45 -0600 |
| Message-ID | <Vv-dncLMpJl_C0_CnZ2dnUU7-a_NnZ2d@giganews.com> |
| In reply to | #156940 |
In article <YlLyH.89633$J736.63364@fx42.ams4>, Bart <bc@freeuk.com> wrote:
>On 05/12/2020 02:19, Ben Bacarisse wrote:
>The following is a more specific pattern that for me occurs over and
>over again (the switch-cases and if-else chains or nested switch-case
>are usually much longer):
>
> switch (a) {
> case 10:
> if (a)
> else if (b)
> else
> <error handling code>
> break;
> case 20
> if (c)
> if (x) <error handling code>
> else if (d)
> else
> <error handling code>
> break;
> default:
> <error handling code>
> }
>
>The error code is the same in each case (and can use locals so is not
>practical to off-load to a function) This statement is not the last
>thing in a function, so it is not cleanup code at the end of a function
>like the other examples in the thread.
>
>What is the simplest solution in C?
Again, often handling this at a higher level makes sense: put the switch
in a subroutine, and the error handling code in the caller. Letting
a routine cleanly "return" is usually easiest to follow.
To make this exact code work without duplicating error handling code,
set handle_err = 1, and clear it to 0 on any successful path. This removes
the default case.
handle_err = 1;
switch(a) {
case 10:
if (a) {
handle_err = 0;
...
} else if (b) {
handle_err = 0;
}
break;
case 20:
if (c) {
handle_err = 0;
...
if(x) {
handle_err = 1;
}
} else if (d) {
handle_err = 0;
}
break;
}
if(handle_err) {
< error handling code >
}
I put the code in my style (always use { } on all if/while/for statements--
this is a good rule to follow always, density is nice, not debugging the
same stupid type of bug is better).
If you put your code in the same style, and use goto to jump to the shared
error handler, this is one line longer. If you remove the new unneeded
break for "case 20:", it's the same number of lines.
Kent
[toc] | [prev] | [next] | [standalone]
| From | Vir Campestris <vir.campestris@invalid.invalid> |
|---|---|
| Date | 2020-12-07 21:43 +0000 |
| Message-ID | <rqm7md$ofs$1@dont-email.me> |
| In reply to | #156928 |
On 05/12/2020 02:19, Ben Bacarisse wrote:
> Not necessarily; that's an overly general claim:
>
> char *buffer = 0, *workspace = 0;
> FILE *fp = 0;
>
> // get what we need...
> if ((buffer = malloc(2*SIZE)) &&
> (workspace = malloc(SIZE)) &&
> (fp = fopen(fname, "r"))) {
> // meat of the function...
> }
>
> // cleanup...
> free(buffer);
> free(workspace);
> if (fp) fclose(fp);
>
> Depending on the situation, one might even get away with
>
> char *buffer = malloc(2*SIZE),
> *workspace = malloc(SIZE);
> FILE *fp = fopen(fname, "r");
>
> if (buffer && workspace && fp) {
> // meat of the function...
> }
>
> // cleanup...
> free(buffer);
> free(workspace);
> if (fp) fclose(fp);
>
> There's been a lot of talk about code looking "clean", but I like code
> to be easy to reason about, and goto can seriously mess that up.
That's OK when your resource allocation statements are, like those,
trivially small, likely to succeed, and don't have dependencies.
That's not always the case.
Suppose we have:
buffer = alphafunc();
//20 lines of code to process buffer,
// with several potential fail points
workspace = betafunc(buffer);
That makes the if pattern harder to use.
Andy
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2020-12-07 23:02 +0000 |
| Message-ID | <87r1o1md82.fsf@bsb.me.uk> |
| In reply to | #157048 |
Vir Campestris <vir.campestris@invalid.invalid> writes:
> On 05/12/2020 02:19, Ben Bacarisse wrote:
>> Not necessarily; that's an overly general claim:
>>
>> char *buffer = 0, *workspace = 0;
>> FILE *fp = 0;
>>
>> // get what we need...
>> if ((buffer = malloc(2*SIZE)) &&
>> (workspace = malloc(SIZE)) &&
>> (fp = fopen(fname, "r"))) {
>> // meat of the function...
>> }
>>
>> // cleanup...
>> free(buffer);
>> free(workspace);
>> if (fp) fclose(fp);
>>
>> Depending on the situation, one might even get away with
>>
>> char *buffer = malloc(2*SIZE),
>> *workspace = malloc(SIZE);
>> FILE *fp = fopen(fname, "r");
>>
>> if (buffer && workspace && fp) {
>> // meat of the function...
>> }
>>
>> // cleanup...
>> free(buffer);
>> free(workspace);
>> if (fp) fclose(fp);
>>
>> There's been a lot of talk about code looking "clean", but I like code
>> to be easy to reason about, and goto can seriously mess that up.
>
> That's OK when your resource allocation statements are, like those,
> trivially small, likely to succeed, and don't have dependencies.
>
> That's not always the case.
>
> Suppose we have:
> buffer = alphafunc();
> //20 lines of code to process buffer,
> // with several potential fail points
> workspace = betafunc(buffer);
>
> That makes the if pattern harder to use.
These rather generic examples make me wary. What are these lines of
code, and why are they not part of an initialisation function? I'd
really like to see an actual example.
The case that has cropped up a few times for me is the construction of a
dynamic structure, for example an allocated array of allocated arrays.
But every time I've written it, one way or another, the allocations all
end up in a function.
--
Ben.
[toc] | [prev] | [next] | [standalone]
Page 5 of 6 — ← Prev page 1 2 3 4 [5] 6 Next page →
Back to top | Article view | comp.lang.c
csiph-web