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


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

Learning functions; roots of the quadratic; two return values

Started byAlla _ <modelling.data@gmail.com>
First post2015-10-03 10:43 -0700
Last post2015-10-06 07:34 +0200
Articles 20 on this page of 104 — 24 participants

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


Contents

  Learning functions; roots of the quadratic; two return values Alla _ <modelling.data@gmail.com> - 2015-10-03 10:43 -0700
    Re: Learning functions; roots of the quadratic; two return values Andrew Cooper <amc96@cam.ac.uk> - 2015-10-03 19:00 +0100
      Re: Learning functions; roots of the quadratic; two return values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-03 19:34 +0100
        Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-03 21:29 +0200
          Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-03 21:36 +0200
          Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-03 21:43 +0200
          Re: Learning functions; roots of the quadratic; two return values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-03 20:46 +0100
            Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-03 22:46 +0200
              Re: Learning functions; roots of the quadratic; two return values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-03 23:18 +0100
                Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-04 01:08 +0200
                Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-04 01:36 +0200
                  Re: Learning functions; roots of the quadratic; two return values Ian Collins <ian-news@hotmail.com> - 2015-10-04 12:52 +1300
                  Re: Learning functions; roots of the quadratic; two return values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-04 15:42 +0100
            Re: Learning functions; roots of the quadratic; two return values jacobnavia <jacob@jacob.remcomp.fr> - 2015-10-03 23:05 +0200
              Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-03 23:41 +0200
                Re: Learning functions; roots of the quadratic; two return values jacobnavia <jacob@jacob.remcomp.fr> - 2015-10-04 00:14 +0200
              Re: Learning functions; roots of the quadratic; two return values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-03 23:07 +0100
                Re: Learning functions; roots of the quadratic; two return values jacobnavia <jacob@jacob.remcomp.fr> - 2015-10-04 00:32 +0200
                Re: Learning functions; roots of the quadratic; two return values Keith Thompson <kst-u@mib.org> - 2015-10-04 12:56 -0700
                  Re: Learning functions; roots of the quadratic; two return values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-04 23:41 +0100
                    Re: Learning functions; roots of the quadratic; two return values Keith Thompson <kst-u@mib.org> - 2015-10-04 18:24 -0700
                Re: Learning functions; roots of the quadratic; two return values James Kuyper <jameskuyper@verizon.net> - 2015-10-04 16:36 -0400
                  Re: Learning functions; roots of the quadratic; two return values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-05 00:01 +0100
                    Re: Learning functions; roots of the quadratic; two return values James Kuyper <jameskuyper@verizon.net> - 2015-10-04 19:24 -0400
            Re: Learning functions; roots of the quadratic; two return values Ian Collins <ian-news@hotmail.com> - 2015-10-04 10:18 +1300
              Re: Learning functions; roots of the quadratic; two return values jacobnavia <jacob@jacob.remcomp.fr> - 2015-10-03 23:27 +0200
                Re: Learning functions; roots of the quadratic; two return values Ian Collins <ian-news@hotmail.com> - 2015-10-04 11:08 +1300
                  Re: Learning functions; roots of the quadratic; two return values Richard Damon <Richard@Damon-Family.org> - 2015-10-03 18:38 -0400
                    Re: Learning functions; roots of the quadratic; two return values Ian Collins <ian-news@hotmail.com> - 2015-10-04 11:47 +1300
            Re: Learning functions; roots of the quadratic; two return values raltbos@xs4all.nl (Richard Bos) - 2015-10-04 14:07 +0000
              Re: Learning functions; roots of the quadratic; two return values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-04 15:48 +0100
                Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-04 18:59 +0200
                  Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-04 20:06 +0200
                Re: Learning functions; roots of the quadratic; two return values Tim Rentsch <txr@alumni.caltech.edu> - 2015-10-04 15:21 -0700
                  Re: Learning functions; roots of the quadratic; two return values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-05 05:25 +0000
          Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-03 21:48 +0200
            Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-04 00:31 +0200
      Re: Learning functions; roots of the quadratic; two return values alla.rashitova@gmail.com - 2015-10-05 08:40 -0700
        Re: Learning functions; roots of the quadratic; two return values Richard Heathfield <rjh@cpax.org.uk> - 2015-10-05 17:10 +0100
        Re: Learning functions; roots of the quadratic; two return values Barry Schwarz <schwarzb@dqel.com> - 2015-10-05 10:41 -0700
    Re: Learning functions; roots of the quadratic; two return values "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-10-03 12:04 -0700
      Re: Learning functions; roots of the quadratic; two return values Philip Lantz <prl@canterey.us> - 2015-10-03 12:48 -0700
      Re: Learning functions; roots of the quadratic; two return values Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-03 20:55 +0100
        Re: Learning functions; roots of the quadratic; two return values "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2015-10-03 13:27 -0700
        Re: Learning functions; roots of the quadratic; two return values jacobnavia <jacob@jacob.remcomp.fr> - 2015-10-03 23:08 +0200
          Re: Learning functions; roots of the quadratic; two return values Richard Heathfield <rjh@cpax.org.uk> - 2015-10-03 22:52 +0100
      Re: Learning functions; roots of the quadratic; two return values Rosario19 <Ros@invalid.invalid> - 2015-10-04 20:46 +0200
        Re: Learning functions; roots of the quadratic; two return values Keith Thompson <kst-u@mib.org> - 2015-10-04 15:47 -0700
        Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-05 03:06 +0200
          Re: Learning functions; roots of the quadratic; two return values Rosario19 <Ros@invalid.invalid> - 2015-10-05 05:31 +0200
            Re: Learning functions; roots of the quadratic; two return values Rosario19 <Ros@invalid.invalid> - 2015-10-05 11:58 +0200
              Re: Learning functions; roots of the quadratic; two return values Rosario19 <Ros@invalid.invalid> - 2015-10-05 12:00 +0200
                Re: Learning functions; roots of the quadratic; two return values Rosario19 <Ros@invalid.invalid> - 2015-10-05 12:06 +0200
            Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-05 12:39 +0200
              Re: Learning functions; roots of the quadratic; two return values Bartc <bc@freeuk.com> - 2015-10-05 12:20 +0100
                Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-05 13:50 +0200
                Re: Learning functions; roots of the quadratic; two return values Richard Heathfield <rjh@cpax.org.uk> - 2015-10-05 12:57 +0100
          Re: Learning functions; roots of the quadratic; two return values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-05 05:40 +0000
            Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-05 08:30 +0200
            Re: Learning functions; roots of the quadratic; two return values Philip Lantz <prl@canterey.us> - 2015-10-05 10:03 -0700
              Re: Learning functions; roots of the quadratic; two return values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-05 22:25 +0000
                Re: Learning functions; roots of the quadratic; two return values James Kuyper <jameskuyper@verizon.net> - 2015-10-05 19:26 -0400
                  Re: Learning functions; roots of the quadratic; two return values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-06 03:44 +0000
                    Re: Learning functions; roots of the quadratic; two return values James Kuyper <jameskuyper@verizon.net> - 2015-10-06 10:55 -0400
                      Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-06 23:07 +0200
                        Re: Learning functions; roots of the quadratic; two return values James Kuyper <jameskuyper@verizon.net> - 2015-10-06 18:35 -0400
                          Re: Learning functions; roots of the quadratic; two return values raltbos@xs4all.nl (Richard Bos) - 2015-10-14 11:08 +0000
                          Re: Learning functions; roots of the quadratic; two return values James Kuyper <jameskuyper@verizon.net> - 2015-10-14 11:11 -0400
                            Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-14 22:22 +0200
                              Re: Learning functions; roots of the quadratic; two return values James Kuyper <jameskuyper@verizon.net> - 2015-10-14 17:17 -0400
                                Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-14 23:45 +0200
                            Re: Learning functions; roots of the quadratic; two return values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-15 00:11 +0000
                              Re: Learning functions; roots of the quadratic; two return values Bartc <bc@freeuk.com> - 2015-10-15 01:37 +0100
                                Re: Learning functions; roots of the quadratic; two return values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-15 05:52 +0000
                              Re: Learning functions; roots of the quadratic; two return values James Kuyper <jameskuyper@verizon.net> - 2015-10-14 21:54 -0400
                                Re: Learning functions; roots of the quadratic; two return values asetofsymbols@gmail.com - 2015-10-14 22:40 -0700
                                  Re: Learning functions; roots of the quadratic; two return values asetofsymbols@gmail.com - 2015-10-15 05:00 -0700
                                  Re: Learning functions; roots of the quadratic; two return values supercat@casperkitty.com - 2015-10-15 11:58 -0700
                                Re: Learning functions; roots of the quadratic; two return values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-15 06:04 +0000
                      Re: Learning functions; roots of the quadratic; two return values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-06 23:18 +0000
                        Re: Learning functions; roots of the quadratic; two return values supercat@casperkitty.com - 2015-10-06 16:31 -0700
                          Re: Learning functions; roots of the quadratic; two return values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-07 00:38 +0000
                            Re: Learning functions; roots of the quadratic; two return values supercat@casperkitty.com - 2015-10-06 21:19 -0700
                        Re: Learning functions; roots of the quadratic; two return values James Kuyper <jameskuyper@verizon.net> - 2015-10-06 22:15 -0400
                          Re: Learning functions; roots of the quadratic; two return values glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-07 08:45 +0000
                        Re: Learning functions; roots of the quadratic; two return values Melzzzzz <mel@zzzzz.com> - 2015-10-07 05:19 +0200
                          Re: Learning functions; roots of the quadratic; two return values Keith Thompson <kst-u@mib.org> - 2015-10-07 09:12 -0700
                            Re: Learning functions; roots of the quadratic; two return values Melzzzzz <mel@zzzzz.com> - 2015-10-08 00:53 +0200
                              Re: Learning functions; roots of the quadratic; two return values Keith Thompson <kst-u@mib.org> - 2015-10-07 16:23 -0700
                Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-06 02:16 +0200
                  Re: Learning functions; roots of the quadratic; two return values supercat@casperkitty.com - 2015-10-06 15:43 -0700
                    Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-07 02:48 +0200
                      Re: Learning functions; roots of the quadratic; two return values Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-10-14 14:00 -0700
                        Re: Learning functions; roots of the quadratic; two return values regis <regis.barbanchon@free.fr> - 2015-10-14 23:23 +0200
    Re: Learning functions; roots of the quadratic; two return values Geoff <geoff@invalid.invalid> - 2015-10-03 12:50 -0700
    Re: Learning functions; roots of the quadratic; two return values Bartc <bc@freeuk.com> - 2015-10-03 21:16 +0100
      Re: Learning functions; roots of the quadratic; two return values alla.rashitova@gmail.com - 2015-10-05 09:02 -0700
        Re: Learning functions; roots of the quadratic; two return values Richard Heathfield <rjh@cpax.org.uk> - 2015-10-05 17:13 +0100
    Re: Learning functions; roots of the quadratic; two return values Barry Schwarz <schwarzb@dqel.com> - 2015-10-03 15:37 -0700
    Re: Learning functions; roots of the quadratic; two return values Rosario19 <Ros@invalid.invalid> - 2015-10-05 23:44 +0200
      Re: Learning functions; roots of the quadratic; two return values Geoff <geoff@invalid.invalid> - 2015-10-05 18:37 -0700
      Re: Learning functions; roots of the quadratic; two return values Barry Schwarz <schwarzb@dqel.com> - 2015-10-05 19:24 -0700
        Re: Learning functions; roots of the quadratic; two return values Rosario19 <Ros@invalid.invalid> - 2015-10-06 07:36 +0200
      Re: Learning functions; roots of the quadratic; two return values Rosario19 <Ros@invalid.invalid> - 2015-10-06 07:34 +0200

Page 1 of 6  [1] 2 3 4 5 6  Next page →


#71692 — Learning functions; roots of the quadratic; two return values

FromAlla _ <modelling.data@gmail.com>
Date2015-10-03 10:43 -0700
SubjectLearning functions; roots of the quadratic; two return values
Message-ID<cb70be98-6d3b-4814-bd1d-37289fa8d0b7@googlegroups.com>
Hello!

Below is a program which should have a few functions:

1) the function that finds two roots of a quadratic
2) the function to turn a value into an absolute value
3) to find approximate square root (which uses the above 
absolute-value function) (please, note that I am following 
the material from the book, and I am not yet ready for 
sophisticated functions to find a square root)

Quadratic has two roots, hence my square root function
should return two values x1 and x2. Please, take a look
at the program: what is my mistake, and why I don't get 
any answer? I assume one of the reasons is that I don't 
have any %-tags in my printf function, but when I add
two %f, I get an error message from a compiler, because 
then I have only "one" argument, i.e. solve_quadratic(a,b,c).

#include <stdio.h>
#include <math.h>

float abs_value (float x);
float approx_sqrt (float x);
float solve_quadratic (float a, float b, float c);

// The main function prompts the user for 3 constant values to fill a quadratic
// ax^2 + bx + c
int main(void)
{
    float a, b, c;
    
    printf("Please, enter three constants of the quadratic:   \n");
    
    if (scanf ("%f %f %f", &a, &b, &c) == 3) 
        printf("Square roots of this quadratic are: %f and %f\n", solve_quadratic(a,b,c));
    
    return 0;
}

// Function to take an absolute value of x that is used further in square root function
float abs_value (float x)
{
    if (x < 0)
        x = - x;
    return x;
}

// Function to compute an approximate square root - Newton Raphson method
float approx_sqrt (float x)
{
    float guess = 1;
    
    while (abs_value (pow(guess,2) / x) > 1.001 || abs_value (pow(guess,2) / x) < 0.999)
          guess = (x / guess + guess) / 2.0;
    
    return guess;
}

// Function to find roots of a quadratic
float solve_quadratic (float a, float b, float c)
{
    float x1, x2;
    float discriminant = pow(b,2) - 4 * a * c;
    
    if (discriminant < 0)
    {
        printf("Roots are imaginary\n");
        return -1;
    }
    else
    {
        x1 = (-b + approx_sqrt(discriminant)) / (2 * a);
        x2 = (-b - approx_sqrt(discriminant)) / (2 * a);
    }
    
    return x1, x2;
}

Thank you!

[toc] | [next] | [standalone]


#71694

FromAndrew Cooper <amc96@cam.ac.uk>
Date2015-10-03 19:00 +0100
Message-ID<mup52t$b69$1@flame.srcf.net>
In reply to#71692
On 03/10/2015 18:43, Alla _ wrote:
> // Function to find roots of a quadratic
> float solve_quadratic (float a, float b, float c)
> {
>     float x1, x2;
>     float discriminant = pow(b,2) - 4 * a * c;
>     
>     if (discriminant < 0)
>     {
>         printf("Roots are imaginary\n");
>         return -1;
>     }
>     else
>     {
>         x1 = (-b + approx_sqrt(discriminant)) / (2 * a);
>         x2 = (-b - approx_sqrt(discriminant)) / (2 * a);
>     }
>     
>     return x1, x2;

Your problem is that this statement, while legal C syntax, does not do
what you intend.  It is an instance of the comma operator.

It is not possible to return multiple values like this in C.  Instead,
you should pass the results back by pointer.

e.g.

void solve_quadratic (float a, float b, float c, float *r1, float *r2)
{
    ... as before

    *r1 = x1;
    *r2 = x2;
}

And the caller should provide pointers to variables, with which to
receive the answers.

float r1, r2;

solve_quadratic(a, b, c, &r1, &r2);
printf("Square roots of this quadratic are: %f and %f\n", r1, r2);

~Andrew

[toc] | [prev] | [next] | [standalone]


#71699

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-10-03 19:34 +0100
Message-ID<87eghbpzr2.fsf@bsb.me.uk>
In reply to#71694
Andrew Cooper <amc96@cam.ac.uk> writes:

> On 03/10/2015 18:43, Alla _ wrote:
>> // Function to find roots of a quadratic
>> float solve_quadratic (float a, float b, float c)
>> {
>>     float x1, x2;
>>     float discriminant = pow(b,2) - 4 * a * c;
>>     
>>     if (discriminant < 0)
>>     {
>>         printf("Roots are imaginary\n");

In general, utility functions like this should not print messages like
this.  It limits how they can be used later.

>>         return -1;
>>     }
>>     else
>>     {
>>         x1 = (-b + approx_sqrt(discriminant)) / (2 * a);
>>         x2 = (-b - approx_sqrt(discriminant)) / (2 * a);
>>     }
>>     
>>     return x1, x2;
>
> Your problem is that this statement, while legal C syntax, does not do
> what you intend.  It is an instance of the comma operator.
>
> It is not possible to return multiple values like this in C.  Instead,
> you should pass the results back by pointer.
>
> e.g.
>
> void solve_quadratic (float a, float b, float c, float *r1, float *r2)
> {
>     ... as before

Since the function can fail to find real roots, it makes sense to signal
success or failure via the return value:

  bool solve_quadratic(float a, float b, float c, float *r1, float *r2)

I find I write very few void functions.  It's very rare that there is
not some value that can be usefully returned so whenever I start to type
"void xxx(..." I make myself stop and think if I can't make use of the
return value.

<snip>

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#71711

Fromregis <regis.barbanchon@free.fr>
Date2015-10-03 21:29 +0200
Message-ID<56102ca0$0$3053$426a74cc@news.free.fr>
In reply to#71699
On 10/03/15 20:34, Ben Bacarisse wrote:

> Since the function can fail to find real roots, it makes sense to signal
> success or failure via the return value:
>
>    bool solve_quadratic(float a, float b, float c, float *r1, float *r2)
>
> I find I write very few void functions.  It's very rare that there is
> not some value that can be usefully returned so whenever I start to type
> "void xxx(..." I make myself stop and think if I can't make use of the
> return value.

I would make the function always succeed,
and return a list of 0, 1, or 2 roots through a structure.
Something along the lines:

#include <math.h>
#include <assert.h>

double DoubleIsCloseToZero (double value);
double Discriminant (double a, double b, double c);
double CountRootsFromDiscriminant (double delta);

typedef struct { int count; double values[2]; } QuadRoots;

QuadRoots
SolveQuadEquation (double a, double b, double c)
{
   assert ( ! DoubleIsCloseToZero (a));

   double delta= Discriminant (a, b, c);
   int count= CountRootsFromDiscriminant (delta);
   if (count == 0) return (QuadRoots){ .count= 0, .values= {} };
   if (count == 1) return (QuadRoots){ .count= 1, .values= {-b/(2*a)} };

   double sqrtDelta= sqrt (delta);
   double root0= (-b - sqrtDelta)/(2*a);
   double root1= (-b + sqrtDelta)/(2*a);
   return (QuadRoots){ .count= 2, .values= {root0, root1} };
}

-- 
Regis

[toc] | [prev] | [next] | [standalone]


#71715

Fromregis <regis.barbanchon@free.fr>
Date2015-10-03 21:36 +0200
Message-ID<56102e43$0$3042$426a34cc@news.free.fr>
In reply to#71711
On 10/03/15 21:29, regis wrote:
>
> double DoubleIsCloseToZero (double value);

(ooops this predicate should of course return a bool ;o)

bool DoubleIsCloseToZero (double value);

--
regis

[toc] | [prev] | [next] | [standalone]


#71717

Fromregis <regis.barbanchon@free.fr>
Date2015-10-03 21:43 +0200
Message-ID<56102ff8$0$3339$426a74cc@news.free.fr>
In reply to#71711
On 10/03/15 21:29, regis wrote:
> double CountRootsFromDiscriminant (double delta);

(ooops #2 this function should of course return an int ;o)

int CountRootsFromDiscriminant (double delta);

[toc] | [prev] | [next] | [standalone]


#71718

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-10-03 20:46 +0100
Message-ID<8737xrpwf0.fsf@bsb.me.uk>
In reply to#71711
regis <regis.barbanchon@free.fr> writes:

> On 10/03/15 20:34, Ben Bacarisse wrote:
>
>> Since the function can fail to find real roots, it makes sense to signal
>> success or failure via the return value:
>>
>>    bool solve_quadratic(float a, float b, float c, float *r1, float *r2)
>>
>> I find I write very few void functions.  It's very rare that there is
>> not some value that can be usefully returned so whenever I start to type
>> "void xxx(..." I make myself stop and think if I can't make use of the
>> return value.
>
> I would make the function always succeed,
> and return a list of 0, 1, or 2 roots through a structure.
> Something along the lines:
>
> #include <math.h>
> #include <assert.h>
>
> double DoubleIsCloseToZero (double value);
> double Discriminant (double a, double b, double c);
> double CountRootsFromDiscriminant (double delta);
>
> typedef struct { int count; double values[2]; } QuadRoots;
>
> QuadRoots
> SolveQuadEquation (double a, double b, double c)

It's generally regarded as bad style to return objects this large from a
C function.  It works, but it can imply a lot of copying.  Of course,
that hardly matters if the function is used few times, but one can image
a root-finding function being called a lot in some programs.

I'm not sure I agree with that assessment, because compilers are getting
better and better at optimising out this copying, but I think it would
be fair to say that the most C-like way to do this would be:

  int SolveQuadEquation(double a, double b, double c, double *roots);

with the return value counting the roots, and a pointer being passed to
(the start of) a plain double array to receive them.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#71732

Fromregis <regis.barbanchon@free.fr>
Date2015-10-03 22:46 +0200
Message-ID<56103ea4$0$21266$426a74cc@news.free.fr>
In reply to#71718
On 10/03/15 21:46, Ben Bacarisse wrote:

> It's generally regarded as bad style to return objects this large from a
> C function.

It's not a style issue, it's a design issue.

> It works, but it can imply a lot of copying.  Of course,
> that hardly matters if the function is used few times, but one can image
> a root-finding function being called a lot in some programs.

It looks like premature optimization to me.
Furthermore, the context here is not optimization.
It's obviously about learning a first imperative language:
first functions, first conditionnals, etc.

Some Teachers love these kind of exercises because if you deal with
all degenerate cases (a=0, a=b=0, a=b=c=0) inside a single function,
their code will contain a lot of nested conditionals,
which they think is the bread and butter of programming.

While in fact, programming is nowadays all about functions doing only 
one thing, and removing deep nesting by applying refactorings such as:
- reordering conditionals,
- early exit through guard clauses,
- and extracting functions.

> I'm not sure I agree with that assessment, because compilers are getting
> better and better at optimising out this copying, but I think it would
> be fair to say that the most C-like way to do this would be:
>
>    int SolveQuadEquation(double a, double b, double c, double *roots);
>
> with the return value counting the roots, and a pointer being passed to
> (the start of) a plain double array to receive them.

I have no objection about this design, but I have one about style:

If your double* roots parameter expects to meet an array of two doubles 
in the argument, then why hide it to your reader ?
Why not auto-document it in the signature:

int SolveQuadEquation(double a, double b, double c, double roots[2]);

The compiler does not check that the argument points to an array,
let alone an array of the right size, but at least it tells
the user about what roots is supposed to point to.

This, is a style issue ;o)

Regis



[toc] | [prev] | [next] | [standalone]


#71750

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-10-03 23:18 +0100
Message-ID<87eghboatw.fsf@bsb.me.uk>
In reply to#71732
regis <regis.barbanchon@free.fr> writes:

> On 10/03/15 21:46, Ben Bacarisse wrote:
>
>> It's generally regarded as bad style to return objects this large from a
>> C function.
>
> It's not a style issue, it's a design issue.

That's rather too dogmatic for my taste but I accept that this is how
you use the terms.

>> It works, but it can imply a lot of copying.  Of course,
>> that hardly matters if the function is used few times, but one can image
>> a root-finding function being called a lot in some programs.
>
> It looks like premature optimization to me.

Yes, it is.  I think my point was not well made.  I intended to say
simply that the code was not idiomatic C (though I suspect I may be a
decade behind the curve on what's idiomatic).  Lots of idiomatic C
results from applying premature optimisation.  I agree that my
suggestion is in that category.

<snip>
>> I'm not sure I agree with that assessment, because compilers are getting
>> better and better at optimising out this copying, but I think it would
>> be fair to say that the most C-like way to do this would be:
>>
>>    int SolveQuadEquation(double a, double b, double c, double *roots);
>>
>> with the return value counting the roots, and a pointer being passed to
>> (the start of) a plain double array to receive them.
>
> I have no objection about this design, but I have one about style:
>
> If your double* roots parameter expects to meet an array of two
> doubles in the argument, then why hide it to your reader ?
> Why not auto-document it in the signature:
>
> int SolveQuadEquation(double a, double b, double c, double roots[2]);

Why not do it the standard way:

  int SolveQuadEquation(double a, double b, double c,
                        double roots[static 2]);

?  Doing anything else in what is clearly C99 code looks a little odd, I
think.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#71761

Fromregis <regis.barbanchon@free.fr>
Date2015-10-04 01:08 +0200
Message-ID<5610600a$0$3352$426a34cc@news.free.fr>
In reply to#71750
On 10/04/15 00:18, Ben Bacarisse wrote:

>> If your double* roots parameter expects to meet an array of two
>> >doubles in the argument, then why hide it to your reader ?
>> >Why not auto-document it in the signature:
>> >
>> >int SolveQuadEquation(double a, double b, double c, double roots[2]);
> Why not do it the standard way:
>
>    int SolveQuadEquation(double a, double b, double c,
>                          double roots[static 2]);
>
> ?  Doing anything else in what is clearly C99 code looks a little odd, I
> think.


Deal ;o)



[toc] | [prev] | [next] | [standalone]


#71764

Fromregis <regis.barbanchon@free.fr>
Date2015-10-04 01:36 +0200
Message-ID<56106683$0$3164$426a34cc@news.free.fr>
In reply to#71750
On 10/04/15 00:18, Ben Bacarisse wrote:

>> >It looks like premature optimization to me.

> Yes, it is.  I think my point was not well made.  I intended to say
> simply that the code was not idiomatic C (though I suspect I may be a
> decade behind the curve on what's idiomatic).  Lots of idiomatic C
> results from applying premature optimisation.  I agree that my
> suggestion is in that category.

25 years in fact ;o) returning structures is already in C89.
And there is even a div() function that returns a div_t structure
in this standard...

C programmers are prolly the most conservative people on Earth.

They refuse to adopt new standard features
because they are not "idiomatic" (of course: they are new!).
In turn, these features never become idiomatic as they should,
since they are left unused. The argument then becomes somewhat cyclical.

The humans will have lost their pinky toe long before
some C programmers accept returning structures as idiomatic.
I wonder why do they even accept their language be revised every decade.

lol.

-- 
Regis

[toc] | [prev] | [next] | [standalone]


#71766

FromIan Collins <ian-news@hotmail.com>
Date2015-10-04 12:52 +1300
Message-ID<d7b822F2qdvU4@mid.individual.net>
In reply to#71764
regis wrote:
> On 10/04/15 00:18, Ben Bacarisse wrote:
>
>>>> It looks like premature optimization to me.
>
>> Yes, it is.  I think my point was not well made.  I intended to say
>> simply that the code was not idiomatic C (though I suspect I may be a
>> decade behind the curve on what's idiomatic).  Lots of idiomatic C
>> results from applying premature optimisation.  I agree that my
>> suggestion is in that category.
>
> 25 years in fact ;o) returning structures is already in C89.
> And there is even a div() function that returns a div_t structure
> in this standard...
>
> C programmers are prolly the most conservative people on Earth.
>
> They refuse to adopt new standard features
> because they are not "idiomatic" (of course: they are new!).
> In turn, these features never become idiomatic as they should,
> since they are left unused. The argument then becomes somewhat cyclical.
>
> The humans will have lost their pinky toe long before
> some C programmers accept returning structures as idiomatic.
> I wonder why do they even accept their language be revised every decade.

Many don't!

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#71812

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-10-04 15:42 +0100
Message-ID<87eghan1a9.fsf@bsb.me.uk>
In reply to#71764
regis <regis.barbanchon@free.fr> writes:

> On 10/04/15 00:18, Ben Bacarisse wrote:
>
>>> >It looks like premature optimization to me.
>
>> Yes, it is.  I think my point was not well made.  I intended to say
>> simply that the code was not idiomatic C (though I suspect I may be a
>> decade behind the curve on what's idiomatic).  Lots of idiomatic C
>> results from applying premature optimisation.  I agree that my
>> suggestion is in that category.
>
> 25 years in fact ;o) returning structures is already in C89.
> And there is even a div() function that returns a div_t structure
> in this standard...

No!  I meant not idiomatic in this case simply because there is a common
patter that is often used -- return the count and populate a passed-in
array.  There are certainly cases where return a structure is idiomatic.

> C programmers are prolly the most conservative people on Earth.

Maybe.  But not me.  I think some are conservative for good reason (they
are stuck supporting ancient systems) but I have the luxury of using
compound literals and _Generic because I only write C as a hobby these
days.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#71735

Fromjacobnavia <jacob@jacob.remcomp.fr>
Date2015-10-03 23:05 +0200
Message-ID<mupfr1$3l1$1@dont-email.me>
In reply to#71718
Le 03/10/2015 21:46, Ben Bacarisse a écrit :
> It's generally regarded as bad style to return objects this large from a
> C function.  It works, but it can imply a lot of copying.

Not with the lcc compiler. The compiler arranges for passing a pointer 
to the returned structure, and the function is automatically transformed 
into a void function that writes its result into its hidden first argument.

Obviously other compilers like gcc or msvc do the same or similar things.

Note too that an array of two doubles can be returned in a register with 
the AMD/Intel 64 bit architecture. Using the YMM registers the whole 
structure can be returned in a register anyway.

The threshold for "large" is continuisly moving...

[toc] | [prev] | [next] | [standalone]


#71742

Fromregis <regis.barbanchon@free.fr>
Date2015-10-03 23:41 +0200
Message-ID<56104ba4$0$3875$426a74cc@news.free.fr>
In reply to#71735
On 10/03/15 23:05, jacobnavia wrote:
> Le 03/10/2015 21:46, Ben Bacarisse a écrit :
>> It's generally regarded as bad style to return objects this large from a
>> C function.  It works, but it can imply a lot of copying.
>
> Not with the lcc compiler. The compiler arranges for passing a pointer
> to the returned structure, and the function is automatically transformed
> into a void function that writes its result into its hidden first argument.
>
> Obviously other compilers like gcc or msvc do the same or similar things.

If there's any function call left at all,
after inlining triggered by gcc -O2 and clang -O2.

I wrote simple test calling the function once and printing the roots:
I got no function call, except for library functions: printf and sqrt.

-- 
Regis


[toc] | [prev] | [next] | [standalone]


#71748

Fromjacobnavia <jacob@jacob.remcomp.fr>
Date2015-10-04 00:14 +0200
Message-ID<mupjsd$kte$1@dont-email.me>
In reply to#71742
Le 03/10/2015 23:41, regis a écrit :
> If there's any function call left at all,
> after inlining triggered by gcc -O2 and clang -O2.

In this particular case. I was speaking in general about functions that 
return structures by value

[toc] | [prev] | [next] | [standalone]


#71746

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-10-03 23:07 +0100
Message-ID<87oagfobcl.fsf@bsb.me.uk>
In reply to#71735
jacobnavia <jacob@jacob.remcomp.fr> writes:

> Le 03/10/2015 21:46, Ben Bacarisse a écrit :
>> It's generally regarded as bad style to return objects this large from a
>> C function.  It works, but it can imply a lot of copying.
>
> Not with the lcc compiler. The compiler arranges for passing a pointer
> to the returned structure, and the function is automatically
> transformed into a void function that writes its result into its
> hidden first argument.

Yes, that's why I say "can" rather than "does" and why I went on to say
I don't really agree with the conventional wisdom.  I think struct
returns are rather underused.  My point (not well made, I think) is just
that it's not idiomatic C for historical reasons (in fact it was once
not even valid C!).

I tried this with lcc but the code did not compile.  Cutting it down to
a minimal example, the problem seems to be with compound literals that
include an array:

  typedef struct s { double r[2]; };
   
  struct s f1(double a)
  {
       return (struct s){ { a, 0 } };
  }

The error is:

ASGND(INDIRB(ADDRLP(3)), INDIRD(ADDRFP(a)))Error sret2.c: 5  compiler error in _kids--
Bad rule number 0
Error z:\lcc\sret2.c 5 Compiler error (trap). Stopping compilation

lcc -v says "Logiciels/Informatique lcc-win32 version 3.8. Compilation
date: Mar 29 2013 13:11:27" so this may be a fixed bug.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#71754

Fromjacobnavia <jacob@jacob.remcomp.fr>
Date2015-10-04 00:32 +0200
Message-ID<mupktq$p5c$1@dont-email.me>
In reply to#71746
Le 04/10/2015 00:07, Ben Bacarisse a écrit :
> jacobnavia <jacob@jacob.remcomp.fr> writes:
>
>> Le 03/10/2015 21:46, Ben Bacarisse a écrit :
>>> It's generally regarded as bad style to return objects this large from a
>>> C function.  It works, but it can imply a lot of copying.
>>
>> Not with the lcc compiler. The compiler arranges for passing a pointer
>> to the returned structure, and the function is automatically
>> transformed into a void function that writes its result into its
>> hidden first argument.
>
> Yes, that's why I say "can" rather than "does" and why I went on to say
> I don't really agree with the conventional wisdom.  I think struct
> returns are rather underused.  My point (not well made, I think) is just
> that it's not idiomatic C for historical reasons (in fact it was once
> not even valid C!).
>
> I tried this with lcc but the code did not compile.  Cutting it down to
> a minimal example, the problem seems to be with compound literals that
> include an array:
>
>    typedef struct s { double r[2]; };
>
>    struct s f1(double a)
>    {
>         return (struct s){ { a, 0 } };
>    }
>
> The error is:
>
> ASGND(INDIRB(ADDRLP(3)), INDIRD(ADDRFP(a)))Error sret2.c: 5  compiler error in _kids--
> Bad rule number 0
> Error z:\lcc\sret2.c 5 Compiler error (trap). Stopping compilation
>
> lcc -v says "Logiciels/Informatique lcc-win32 version 3.8. Compilation
> date: Mar 29 2013 13:11:27" so this may be a fixed bug.
>
> <snip>
>

Yes, that is a mess. There is the hidden argument, then there is the run 
time evaluation of "a", then there is a cast of an immediate in braces, 
with one member of the array evaluated and the other a constant, that 
have to be shoveled into the hidden  result argument.

On top of that, I optimized recently that an array of two doubles will 
be treated as a single scalar and passed around in the xmm registers 
that can hold that array as a unit. This nullifies the optimization I 
was speaking about since now the arrays of two doubles can be returned 
in a single register... This structure is composed of just two doubles 
so this optimization applies.

Somewhere it hits a bug, and the latest version has it... Thanks for the 
bug report. Will see that I find time to correct that. It looks tough!

jacob

[toc] | [prev] | [next] | [standalone]


#71843

FromKeith Thompson <kst-u@mib.org>
Date2015-10-04 12:56 -0700
Message-ID<lnvbamxv9a.fsf@kst-u.example.com>
In reply to#71746
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
[...]
> I tried this with lcc but the code did not compile.  Cutting it down to
> a minimal example, the problem seems to be with compound literals that
> include an array:
>
>   typedef struct s { double r[2]; };
>    
>   struct s f1(double a)
>   {
>        return (struct s){ { a, 0 } };
>   }

Interesting example.  Is the compound literal necessary to trigger the
bug?  (BTW the "typedef" keyword can be omitted, since you didn't give
it a name.)

Returning a structure that contains an array creates an object with
*temporary lifetime*, a concept that wasn't introduced until C11.
In C99 and earlier, something like

    f1(1.5).r[0]

has undefined, or at least vaguely defined, behavior.  Array indexing
requires an array object, but prior to c11 there is no array object to
be indexed, just an array value that's part of the returned struct
value.

[...]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#71897

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-10-04 23:41 +0100
Message-ID<87mvvyky8c.fsf@bsb.me.uk>
In reply to#71843
Keith Thompson <kst-u@mib.org> writes:

> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> [...]
>> I tried this with lcc but the code did not compile.  Cutting it down to
>> a minimal example, the problem seems to be with compound literals that
>> include an array:
>>
>>   typedef struct s { double r[2]; };
>>    
>>   struct s f1(double a)
>>   {
>>        return (struct s){ { a, 0 } };
>>   }
>
> Interesting example.  Is the compound literal necessary to trigger the
> bug?

I needed (a) a compound literal; (b) with an array member; (c)
initialised with at least one non-constant value.  I didn't try many
combinations of other factors, but that's the smallest case I could find
that resembled the original example code.

> (BTW the "typedef" keyword can be omitted, since you didn't give
> it a name.)

Ah yes, thanks.  It was gradually cut down from a longer program, and I
thought I'd cut all I could!

> Returning a structure that contains an array creates an object with
> *temporary lifetime*, a concept that wasn't introduced until C11.

I was not aware of that change.  I'll go have a look.  Thanks.

> In C99 and earlier, something like
>
>     f1(1.5).r[0]
>
> has undefined, or at least vaguely defined, behavior.  Array indexing
> requires an array object, but prior to c11 there is no array object to
> be indexed, just an array value that's part of the returned struct
> value.

Presumably, in C99, similar problems can occur when a function returns a
union since the re-interpretation that's been discussed elsewhere
requires and object representation and not simply a value.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


Page 1 of 6  [1] 2 3 4 5 6  Next page →

Back to top | Article view | comp.lang.c


csiph-web