Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #156861 > unrolled thread

Effective uses of c `goto' statement

Started bykevin shell <kevin@fedora.osfans.org>
First post2020-12-02 16:42 +0800
Last post2020-12-11 19:27 -0800
Articles 20 on this page of 114 — 24 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#157019

FromBart <bc@freeuk.com>
Date2020-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]


#157033

FromDavid Brown <david.brown@hesbynett.no>
Date2020-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]


#157041

FromBart <bc@freeuk.com>
Date2020-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]


#157043

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2020-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]


#157044

FromBart <bc@freeuk.com>
Date2020-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]


#157045

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2020-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]


#157015

FromDavid Brown <david.brown@hesbynett.no>
Date2020-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]


#157018

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2020-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]


#157022

FromRichard Damon <Richard@Damon-Family.org>
Date2020-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]


#157024

Fromgazelle@shell.xmission.com (Kenny McCormack)
Date2020-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]


#157027

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2020-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]


#157030

FromRichard Damon <Richard@Damon-Family.org>
Date2020-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]


#157036

FromDavid Brown <david.brown@hesbynett.no>
Date2020-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]


#157035

FromDavid Brown <david.brown@hesbynett.no>
Date2020-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]


#157040

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2020-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]


#157056

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2020-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]


#157034

FromDavid Brown <david.brown@hesbynett.no>
Date2020-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]


#157206

Fromkegs@provalid.com (Kent Dickey)
Date2020-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]


#157048

FromVir Campestris <vir.campestris@invalid.invalid>
Date2020-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]


#157058

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2020-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