Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #71692 > unrolled thread
| Started by | Alla _ <modelling.data@gmail.com> |
|---|---|
| First post | 2015-10-03 10:43 -0700 |
| Last post | 2015-10-06 07:34 +0200 |
| Articles | 20 on this page of 104 — 24 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-10-03 10:43 -0700 |
| Subject | Learning 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]
| From | Andrew Cooper <amc96@cam.ac.uk> |
|---|---|
| Date | 2015-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-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]
| From | regis <regis.barbanchon@free.fr> |
|---|---|
| Date | 2015-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]
| From | regis <regis.barbanchon@free.fr> |
|---|---|
| Date | 2015-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]
| From | regis <regis.barbanchon@free.fr> |
|---|---|
| Date | 2015-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-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]
| From | regis <regis.barbanchon@free.fr> |
|---|---|
| Date | 2015-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-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]
| From | regis <regis.barbanchon@free.fr> |
|---|---|
| Date | 2015-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]
| From | regis <regis.barbanchon@free.fr> |
|---|---|
| Date | 2015-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2015-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-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]
| From | jacobnavia <jacob@jacob.remcomp.fr> |
|---|---|
| Date | 2015-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]
| From | regis <regis.barbanchon@free.fr> |
|---|---|
| Date | 2015-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]
| From | jacobnavia <jacob@jacob.remcomp.fr> |
|---|---|
| Date | 2015-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-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]
| From | jacobnavia <jacob@jacob.remcomp.fr> |
|---|---|
| Date | 2015-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-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