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 2 of 6 — ← Prev page 1 [2] 3 4 5 6  Next page →


#71915

FromKeith Thompson <kst-u@mib.org>
Date2015-10-04 18:24 -0700
Message-ID<lnoageumxk.fsf@kst-u.example.com>
In reply to#71897
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Keith Thompson <kst-u@mib.org> writes:
[...]
>> 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.

Yes, it applies to both structures and unions.

N1570 6.2.4p8:

    A non-lvalue expression with structure or union type, where
    the structure or union contains a member with array type
    (including, recursively, members of all contained structures
    and unions) refers to an object with automatic storage
    duration and *temporary lifetime*. Its lifetime begins when
    the expression is evaluated and its initial value is the value
    of the expression. Its lifetime ends when the evaluation of
    the containing full expression or full declarator ends. Any
    attempt to modify an object with temporary lifetime results in
    undefined behavior.

-- 
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]


#71848

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-10-04 16:36 -0400
Message-ID<56118DD5.4010402@verizon.net>
In reply to#71746
On 10/03/2015 06:07 PM, Ben Bacarisse wrote:
...
>   typedef struct s { double r[2]; };

I didn't notice this until I was looking at Keith's reply. I thought
that a typedef declaration requires a declarator, which becomes the
corresponding typedef-name, but I can't find a statement in the standard
to that effect. That declaration doesn't have a declarator. 's' is a
struct tag, not a declarator, so what is the name of the typedef? If it
had been written as

    typedef struct s { double r[2]; } t;

then t would become the corresponding typedef-name. Am I
misunderstanding this?

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


#71889

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-10-05 00:01 +0100
Message-ID<87twq6kzlv.fsf@bsb.me.uk>
In reply to#71848
James Kuyper <jameskuyper@verizon.net> writes:

> On 10/03/2015 06:07 PM, Ben Bacarisse wrote:
> ...
>>   typedef struct s { double r[2]; };
>
> I didn't notice this until I was looking at Keith's reply. I thought
> that a typedef declaration requires a declarator, which becomes the
> corresponding typedef-name, but I can't find a statement in the standard
> to that effect. That declaration doesn't have a declarator. 's' is a
> struct tag, not a declarator, so what is the name of the typedef?

There is none.

> If it
> had been written as
>
>     typedef struct s { double r[2]; } t;
>
> then t would become the corresponding typedef-name. Am I
> misunderstanding this?

No, I think that's about it.  Syntactically, I don't think you need a
declarator in any declaration so all of the following are valid syntax:

  int;
  extern int;
  typedef int;

The curious thing is that when the type-specifier ("int" in the above
example) is a struct-or-union-specifier you get the familiar form:

  struct s { ... };

which has the effect of declaring the struct tag.  This is a
type-specifier standing alone, just like writing "int;" above.

Syntactically you can then add a storage class specifier to this

  extern struct s { ... };
  typedef struct s { ... };

and you get my accidental line.  gcc warns about this but lcc does not,
so I missed it.  This is from the C syntax alone -- I have not checked
to see what constraints the rest of the text puts om these forms, but I
am not surprised that you could not find a requirement for a
declarator to be present.

-- 
Ben.

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


#71895

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-10-04 19:24 -0400
Message-ID<5611B520.4090002@verizon.net>
In reply to#71889
On 10/04/2015 07:01 PM, Ben Bacarisse wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
> 
>> On 10/03/2015 06:07 PM, Ben Bacarisse wrote:
>> ...
>>>   typedef struct s { double r[2]; };
>>
>> I didn't notice this until I was looking at Keith's reply. I thought
>> that a typedef declaration requires a declarator, which becomes the
>> corresponding typedef-name, but I can't find a statement in the standard
>> to that effect. That declaration doesn't have a declarator. 's' is a
>> struct tag, not a declarator, so what is the name of the typedef?
> 
> There is none.
> 
>> If it
>> had been written as
>>
>>     typedef struct s { double r[2]; } t;
>>
>> then t would become the corresponding typedef-name. Am I
>> misunderstanding this?
> 
> No, I think that's about it.  Syntactically, I don't think you need a
> declarator in any declaration so all of the following are valid syntax:
> 
>   int;
>   extern int;
>   typedef int;

True - but they are constraint violations:
"A declaration other than a static_assert declaration shall declare at
least a declarator (other than the parameters of a function or the
members of a structure or union), a tag, or the members of an
enumeration." (6.7p2)

> The curious thing is that when the type-specifier ("int" in the above
> example) is a struct-or-union-specifier you get the familiar form:
> 
>   struct s { ... };
> 
> which has the effect of declaring the struct tag.  This is a
> type-specifier standing alone, just like writing "int;" above.

Yes, a declaration that only declares a tag is allowed by 6.7p2.

> Syntactically you can then add a storage class specifier to this
> 
>   extern struct s { ... };
>   typedef struct s { ... };
> 
> and you get my accidental line.  gcc warns about this but lcc does not,
> so I missed it.  This is from the C syntax alone -- I have not checked
> to see what constraints the rest of the text puts om these forms, but I
> am not surprised that you could not find a requirement for a
> declarator to be present.

There is a constraint, but it isn't violated by your code, which does
declare a struct tag. What it fails to declare is a typedef-name, and it
seems odd to me to allow a typedef declaration that fails to declare a
typedef-name. There should be something prohibiting it somewhere in the
standard, but I haven't found it yet. Possibly, the committee never even
considered this possibility. A similar problem comes up with

typedef enum {red, green, blue};

It satisfies 6.7p2 by declaring enumeration constants, but fails to
declare a typedef-name.

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


#71738

FromIan Collins <ian-news@hotmail.com>
Date2015-10-04 10:18 +1300
Message-ID<d7av1lF2qdvU1@mid.individual.net>
In reply to#71718
Ben Bacarisse wrote:
> 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.

Any C compiler that shares a back end with a C++ compiler should 
optimise away the copy.

-- 
Ian Collins

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


#71739

Fromjacobnavia <jacob@jacob.remcomp.fr>
Date2015-10-03 23:27 +0200
Message-ID<muph3m$7vn$1@dont-email.me>
In reply to#71738
Le 03/10/2015 23:18, Ian Collins a écrit :

> Any C compiler that shares a back end with a C++ compiler should
> optimise away the copy.
>

lcc is a C compiler and optimizes this, just wait a minute, it is very 
old this optimization.

And not related to C++ and to the "this" pointer at all.

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


#71747

FromIan Collins <ian-news@hotmail.com>
Date2015-10-04 11:08 +1300
Message-ID<d7b1usF2qdvU2@mid.individual.net>
In reply to#71739
jacobnavia wrote:
> Le 03/10/2015 23:18, Ian Collins a écrit :
>
>> Any C compiler that shares a back end with a C++ compiler should
>> optimise away the copy.
>>
>
> lcc is a C compiler and optimizes this, just wait a minute, it is very
> old this optimization.

I know it is an old optimisation, but but my point was RVO is a standard 
C++ optimisation.

> And not related to C++ and to the "this" pointer at all.

Who said anything about the this pointer?

-- 
Ian Collins

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


#71757

FromRichard Damon <Richard@Damon-Family.org>
Date2015-10-03 18:38 -0400
Message-ID<jNYPx.18097$Rj5.46@fx02.iad>
In reply to#71747
On 10/3/15 6:08 PM, Ian Collins wrote:
> jacobnavia wrote:
>> Le 03/10/2015 23:18, Ian Collins a écrit :
>>
>>> Any C compiler that shares a back end with a C++ compiler should
>>> optimise away the copy.
>>>
>>
>> lcc is a C compiler and optimizes this, just wait a minute, it is very
>> old this optimization.
>
> I know it is an old optimisation, but but my point was RVO is a standard
> C++ optimisation.
>
>> And not related to C++ and to the "this" pointer at all.
>
> Who said anything about the this pointer?
>

The C++ Standard specifically mentions RVO, as the affect of RVO is 
observable to the program, and thus can't be hidden under the 'as-if' 
rule. C has been able to return struct values since C89 (and likely 
earlier as an 'extension', I don't remember it being allowed in K&R). C 
doesn't need a specific mention of RVO as in C you can't detect it since 
you can't have a user defined copy/move constructor.

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


#71758

FromIan Collins <ian-news@hotmail.com>
Date2015-10-04 11:47 +1300
Message-ID<d7b47gF2qeiU1@mid.individual.net>
In reply to#71757
Richard Damon wrote:
> On 10/3/15 6:08 PM, Ian Collins wrote:
>> jacobnavia wrote:
>>> Le 03/10/2015 23:18, Ian Collins a écrit :
>>>
>>>> Any C compiler that shares a back end with a C++ compiler should
>>>> optimise away the copy.
>>>>
>>>
>>> lcc is a C compiler and optimizes this, just wait a minute, it is very
>>> old this optimization.
>>
>> I know it is an old optimisation, but but my point was RVO is a standard
>> C++ optimisation.
>>
>>> And not related to C++ and to the "this" pointer at all.
>>
>> Who said anything about the this pointer?
>>
>
> The C++ Standard specifically mentions RVO, as the affect of RVO is
> observable to the program, and thus can't be hidden under the 'as-if'
> rule. C has been able to return struct values since C89 (and likely
> earlier as an 'extension', I don't remember it being allowed in K&R). C
> doesn't need a specific mention of RVO as in C you can't detect it since
> you can't have a user defined copy/move constructor.

All true, however as Ben mentioned else-thread, returning a struct isn't 
common in C, so there would have been less of an incentive to focus on 
this particular optimisation.  Returning a struct is common in C++, so 
the there has always been a focus on this optimisation.

-- 
Ian Collins

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


#71809

Fromraltbos@xs4all.nl (Richard Bos)
Date2015-10-04 14:07 +0000
Message-ID<5611325f.1687843@news.xs4all.nl>
In reply to#71718
Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:

> regis <regis.barbanchon@free.fr> writes:
> 
> > 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.

What, one single int and two doubles? No, it isn't. It may be so on
severely limited embedded systems, but in general this is quite
acceptable and indeed just about how I would do it.

Richard

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


#71814

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-10-04 15:48 +0100
Message-ID<878u7in0zo.fsf@bsb.me.uk>
In reply to#71809
raltbos@xs4all.nl (Richard Bos) writes:

> Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>
>> regis <regis.barbanchon@free.fr> writes:
>> 
>> > 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.
>
> What, one single int and two doubles? No, it isn't. It may be so on
> severely limited embedded systems, but in general this is quite
> acceptable and indeed just about how I would do it.

OK.  Noted.  Also note that I might also do it like this too, though I'd
have reservations about defining a struct for this one purpose.  (In
other languages you can return multiple values without explicitly
defining a new type and in such cases it's the obvious thing to do.)

I'd be interested to know how other people see this.  After all, what is
generally accepted can only accessed by hearing lots of opinions.  If
anyone else wants to chime in, could I suggest they distinguish between
what they themselves might do in the case and what the consider
idiomatic or common usage?

-- 
Ben.

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


#71823

Fromregis <regis.barbanchon@free.fr>
Date2015-10-04 18:59 +0200
Message-ID<56115ae1$0$4543$426a74cc@news.free.fr>
In reply to#71814
On 10/04/15 16:48, Ben Bacarisse wrote:
> raltbos@xs4all.nl (Richard Bos) writes:
>
>> Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>>
>>> regis <regis.barbanchon@free.fr> writes:
>>>
>>>> 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.
>>
>> What, one single int and two doubles? No, it isn't. It may be so on
>> severely limited embedded systems, but in general this is quite
>> acceptable and indeed just about how I would do it.
>
> OK.  Noted.  Also note that I might also do it like this too, though I'd
> have reservations about defining a struct for this one purpose.  (In
> other languages you can return multiple values without explicitly
> defining a new type and in such cases it's the obvious thing to do.)

There's no reason to suppose that the story stops there
and that the solving function floats alone in the air...

In fact, the rest of the story here is prolly
one of those boring exercises when you learn first functions in C,
with an interactive loop prompting the user for a equation,
print it, print its roots, and ask for continuation...

Therefore we prolly want the two printing functions:

void PrintQuadEquation (QuadEquation const * eq, FILE * outSteam);
void PrintQuadRoots (QuadRoots const * roots, FILE * outSteam);

and the reading function:

bool ReadQuadEquation (QuadEquation * result, FILE * inStream);

Yes, this means i would pusg further the current design
and introduce a second struct QuadEquation for the coefficients a, b,c 
of the equation itself, constructed with:

QuadEquation MakeQuadEquation (double a, double b, double c);

And the solving function would be refactored like this:

QuadRoots SolveQuadEquation (QuadEquation const * equation);


-- 
Regis


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


#71832

Fromregis <regis.barbanchon@free.fr>
Date2015-10-04 20:06 +0200
Message-ID<56116ab2$0$3861$426a74cc@news.free.fr>
In reply to#71823
On 10/04/15 18:59, regis wrote:

> Therefore we prolly want the two printing functions:
>
> void PrintQuadEquation (QuadEquation const * eq, FILE * outSteam);
> void PrintQuadRoots (QuadRoots const * roots, FILE * outSteam);
>
> And the solving function would be refactored like this:
>
> QuadRoots SolveQuadEquation (QuadEquation const * equation);


And on a second thought, I would consider not even bothering
to pass pointers to constant structures to these three functions,
and simply pass the structures by value:

void PrintQuadEquation (QuadEquation eq, FILE * outSteam);
void PrintQuadRoots (QuadRoots roots, FILE * outSteam);
QuadRoots SolveQuadEquation (QuadEquation equation);

-- 
Regis

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


#71874

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-10-04 15:21 -0700
Message-ID<kfnr3la6zr3.fsf@x-alumni2.alumni.caltech.edu>
In reply to#71814
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> raltbos@xs4all.nl (Richard Bos) writes:
>
>> Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>>
>>> regis <regis.barbanchon@free.fr> writes:
>>>
>>>> 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.
>>
>> What, one single int and two doubles?  No, it isn't.  It may be so
>> on severely limited embedded systems, but in general this is quite
>> acceptable and indeed just about how I would do it.
>
> OK.  Noted.  Also note that I might also do it like this too,
> though I'd have reservations about defining a struct for this one
> purpose.  (In other languages you can return multiple values
> without explicitly defining a new type and in such cases it's the
> obvious thing to do.)
>
> I'd be interested to know how other people see this.  After all,
> what is generally accepted can only accessed by hearing lots of
> opinions.  If anyone else wants to chime in, could I suggest they
> distinguish between what they themselves might do in the case and
> what the consider idiomatic or common usage?

I don't think there's anything wrong with having struct return
values.  At the same time I have a subconscious reluctance to
use them.  Or maybe it's better to say there's a bit of a mental
energy barrier, and I sort of have to convince myself it's okay
in each particular instance.  I speculate that this may be the
result of a chicken-and-egg problem -- compiler writers give
little attention to making struct return values perform well
because people don't use them, and people don't use them because
compilers don't do a good job of handling them.  For sure if
there is a concern about performance I often or usually find
that using struct return values doesn't behave as well as
some other approach to the problem.

Regarding general sentiment, I think it's a complicated question.
Certainly in some circles I expect using struct return values
would be viewed with some amount of skepticism or even derision;
in others I think it wouldn't raise any eyebrows at all, just
business as usual.  So my sense is it's a bit of a mixed bag,
neither generally shunned nor generally accepted.

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


#71941

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2015-10-05 05:25 +0000
Message-ID<mut1k1$4v5$1@speranza.aioe.org>
In reply to#71874
Tim Rentsch <txr@alumni.caltech.edu> wrote:

(snip regarding functions returning struct)

> I don't think there's anything wrong with having struct return
> values.  At the same time I have a subconscious reluctance to
> use them.  Or maybe it's better to say there's a bit of a mental
> energy barrier, and I sort of have to convince myself it's okay
> in each particular instance.  

I agree.  Well, for one I was using C before ANSI, and maybe 
before compilers supported them. But most often, I find pointers
to structs more useful than structs.

Well, OK, that leaves the problem of functions returning pointers
to static storage, and specifically structs. 

> I speculate that this may be the
> result of a chicken-and-egg problem -- compiler writers give
> little attention to making struct return values perform well
> because people don't use them, and people don't use them because
> compilers don't do a good job of handling them.  For sure if
> there is a concern about performance I often or usually find
> that using struct return values doesn't behave as well as
> some other approach to the problem.

But enough problems aren't performance limited, but where 
readability is more important. So the question now, is are
there cases where returning a struct is more readable than the
other ways.
 
> Regarding general sentiment, I think it's a complicated question.
> Certainly in some circles I expect using struct return values
> would be viewed with some amount of skepticism or even derision;
> in others I think it wouldn't raise any eyebrows at all, just
> business as usual.  So my sense is it's a bit of a mixed bag,
> neither generally shunned nor generally accepted.

-- glen

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


#71720

Fromregis <regis.barbanchon@free.fr>
Date2015-10-03 21:48 +0200
Message-ID<561030f4$0$3032$426a34cc@news.free.fr>
In reply to#71711
On 10/03/15 21:29, regis wrote:

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

(revised version after fixing the two faulty signatures...)

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

bool DoubleIsCloseToZero (double value);
double Discriminant (double a, double b, double c);
int 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]


#71753

Fromregis <regis.barbanchon@free.fr>
Date2015-10-04 00:31 +0200
Message-ID<56105729$0$21262$426a74cc@news.free.fr>
In reply to#71720
On 10/03/15 21:48, regis wrote:
>    if (count == 0) return (QuadRoots){ .count= 0, .values= {} };

I should have compiled with -pedantic flag on
as it seems ISO C forbid empty initializer braces, so:

if (count == 0) return (QuadRoots){ .count= 0 };

-- 
regis

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


#71975

Fromalla.rashitova@gmail.com
Date2015-10-05 08:40 -0700
Message-ID<2282ce67-101c-48b0-8f88-fd0362e63593@googlegroups.com>
In reply to#71694
<snip>
Andrew, Thank you very much.
Below is the result, and the program works now.
But I am not sure that I understand the usage 
of these pointers.

Please, take a look at what I think they mean,
and, if possible, please, correct me.

#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, float *root1, float *root2);

// 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, root1, root2;
    
    printf("Please, enter three constants of the quadratic:   \n");
    
    if (scanf ("%f %f %f", &a, &b, &c) == 3)
    {
        solve_quadratic(a, b, c, &root1, &root2); 

/** As I just learned, & operator indicates the address of 
    the given variable, it points to that address; hence, do
    &root1 and &root2 indicate the address of these two 
    variables within the function solve_quadratic? How
    does it work "under the hood"? Does is tell the compiler
    that both root1 and root2 are below, in the function 
    solve_quadratic?
**/ 
        printf("Square roots of this quadratic are: %f and %f\n", root1, root2);
    }
    
    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 *root1, float *root2)

/** What do pointers mean here? why do we use them?
**/
{
    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);
        *root1 = x1;
        *root2 = x2;
    }
}

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


#71979

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-10-05 17:10 +0100
Message-ID<muu794$a2l$1@dont-email.me>
In reply to#71975
On 05/10/15 16:40, alla.rashitova@gmail.com wrote:
> <snip>
> Andrew, Thank you very much.
> Below is the result, and the program works now.
> But I am not sure that I understand the usage
> of these pointers.

Pointers is easy, and don't let anyone tell you different. :-)

(Actually, the detail gets very complicated, but the underlying concept 
is easy.)

Everything has to be somewhere. An 'object' (in your program, a, b, c, 
root1, root2 are all objects) has to exist somewhere in the memory of 
the computer, *and* the computer has to be able to find it when needed. 
So every memory location has an address associated with it, just as your 
house has an address so that the postman can find it.

&x simply means "the place where x is" - i.e. x's address.

We might write:

xaddr = &x;

and this would store the address of x in another object (xaddr). For 
this to be legal C, xaddr has to have "pointer type". A pointer is 
simply an address value.

The * operator, when applied to a pointer such as xaddr as follows:

*xaddr

means "the thing at the address that xaddr is remembering" - so, in this 
case, x.

Why do we use pointers? Lots of reasons, but in C one of the most 
important reasons is that, when you specify a value as a function 
argument, it is the /value/, not the object containing it, that is 
passed to the function. The function is given a new object of the same 
value, which is normally what we want but sometimes we want the function 
to be able to update an object's value, and have that change persist 
("stick", if you like) in the caller. In such a case, we pass the 
address of the object we want to update, and the value of the address is 
passed. The called function can then update the value through that 
address (pointer), using *myparameter, as follows:

i = 6;
printf("Before function call: %d\n", i);
foo(i);
printf("After function call: %d\n", i);

prints:
Before function call: 6
After function call: 6

no matter what foo() does to its parameter. But this code:

i = 6;
printf("Before function call: %d\n", i);
bar(&i);
printf("After function call: %d\n", i);

If bar() is written like this:

void bar(int *pint)
{
   *pint = 42;
}

then the program would print:

Before function call: 6
After function call: 42

> Please, take a look at what I think they mean,
> and, if possible, please, correct me.
>
> #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, float *root1, float *root2);
>
> // 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, root1, root2;
>
>      printf("Please, enter three constants of the quadratic:   \n");
>
>      if (scanf ("%f %f %f", &a, &b, &c) == 3)
>      {
>          solve_quadratic(a, b, c, &root1, &root2);
>
> /** As I just learned, & operator indicates the address of
>      the given variable, it points to that address; hence, do
>      &root1 and &root2 indicate the address of these two
>      variables within the function solve_quadratic?

No, root1 and root2 are local to main(), so &root1 and &root2 indicate 
the address of these two variables within the function main(). Using 
those expressions: &root1, &root2 within the function call means that 
they will be evaluated, and the values (which, for &, are addresses) are 
copied to the parameters of solve_quadratic().

> How does it work "under the hood"? Does is tell the compiler
> that both root1 and root2 are below, in the function
> solve_quadratic?
> **/

See above.

>          printf("Square roots of this quadratic are: %f and %f\n", root1, root2);

On return from solve_quadratic(), root1 and root2 have taken on new 
values. This is possible because you gave (copies of) those objects' 
addresses to solve_quadratic(), which solve_quadratic() could use to 
access the original objects.

> // Function to find roots of a quadratic
> float solve_quadratic (float a, float b, float c, float *root1, float *root2)

The fact that you've used the same name for "first root" and "address of 
first root" (the former in main, the latter in solve_quadratic) is 
unfortunate. (And for "second root" and "address of second root".)

Better names: ptr_root1, ptr_root2 or maybe rootaddr1 and rootaddr2.

Why are they better? Because they indicate that the parameter is a 
pointer, so it isn't itself a root but it points the way to where space 
can be found to store a root. When you're learning (and even when you've 
been doing this for years), it's helpful to choose names that keep 
different ideas separate.

<snip>

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

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


#71993

FromBarry Schwarz <schwarzb@dqel.com>
Date2015-10-05 10:41 -0700
Message-ID<stb51blb6qaunpq06rkkmd8r8j6p4rn382@4ax.com>
In reply to#71975
On Mon, 5 Oct 2015 08:40:55 -0700 (PDT), alla.rashitova@gmail.com
wrote:

><snip>
>Andrew, Thank you very much.
>Below is the result, and the program works now.
>But I am not sure that I understand the usage 
>of these pointers.
>
>Please, take a look at what I think they mean,
>and, if possible, please, correct me.
>
>#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, float *root1, float *root2);

This declaration says you have decided that solve_quadratic should do
two different things.  One is store the two roots of the quadratic in
the float objects pointed to by root1 and root2.  Two is return a
float value via a return statement.

>// The main function prompts the user for 3 constant values to fill a quadratic

They are not constants; they are coefficients.

>// ax^2 + bx + c
>int main(void)
>{
>    float a, b, c, root1, root2;
>    
>    printf("Please, enter three constants of the quadratic:   \n");
>    
>    if (scanf ("%f %f %f", &a, &b, &c) == 3)
>    {
>        solve_quadratic(a, b, c, &root1, &root2); 

Here you have decided to ignore the value "returned" by
solve_quadratic.  If you don't use the value, why return it?

>/** As I just learned, & operator indicates the address of 
>    the given variable, it points to that address; hence, do
>    &root1 and &root2 indicate the address of these two 
>    variables within the function solve_quadratic? How

Richard has already explained why this is wrong.

>    does it work "under the hood"? Does is tell the compiler

At your current state of learning, you should not care.  Furthermore,
there is more than one "hood" and there is no requirement for two
hoods to do it the same way.

>    that both root1 and root2 are below, in the function 
>    solve_quadratic?

And as Richard pointed out, using the same name has caused you some
confusion.

>**/ 
>        printf("Square roots of this quadratic are: %f and %f\n", root1, root2);

There are times when this statement will cause undefined behavior. See
below.

>    }
>    
>    return 0;
>}

<snip>

>// Function to find roots of a quadratic
>float solve_quadratic (float a, float b, float c, float *root1, float *root2)
>
>/** What do pointers mean here? why do we use them?
>**/
>{
>    float x1, x2;
>    float discriminant = pow(b,2) - 4 * a * c;
>    
>    if (discriminant < 0)
>    {
>        printf("Roots are imaginary\n");

While the roots may be imaginary, they are much more likely to be
complex instead.

>        return -1;

Two points:

   1 - You apparently intend the return value to indicate the status
of the function.  It is more conventional to use an int for this
rather than a float.

   2 - At this point you have not placed any values in *root1 or
*root2.  (Remember that since root1 and root2 are pointers in this
function, the notation *root1 refers the object root1 points to which
happens to be the float root1 in main.)  Since root1 and root2 in main
are automatic objects, they are not initialized and each has an
indeterminate value.  When this return statement is executed, main
will pass those indeterminate values to printf which is undefined
behavior.

You have some choices. :

     One is to move the above printf to main in a block of code that
tests the return value of solve_quadratic.  This is my preferred
choice since a negative discriminant does not preclude solving for the
roots.  It is your main function that should decide it does not want
to deal with complex solutions.

     Another is to add some assignment statements prior to the return
statement that will store dummy values in *root1 and *root2 so the
call to printf in main does not invoke undefined behavior.  Since you
print the "error message" here, the user will be warned to ignore the
dummy values.

>    }
>    else
>    {
>        x1 = (-b + approx_sqrt(discriminant)) / (2 * a);
>        x2 = (-b - approx_sqrt(discriminant)) / (2 * a);
>        *root1 = x1;
>        *root2 = x2;

At this point your compiler should have issued a diagnostic.  You
defined the function to return a float and here you exit the function
without returning any value.

>    }
>}

-- 
Remove del for email

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


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

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


csiph-web