NUMERICAL RECIPES

N

nmm1

It's not true in C either.

Strings are not pointers. Arrays are not pointers. Functions are not
pointers.

All three are typically managed using pointers, and a declaration that
looks like a parameter of array or function type is really a pointer
parameter.

Er, no. While I agree that I was over-simplifying, you have seriously
misunderstood C. It is NOT just when they are parameters, but any
time that they are used as values - there is no such thing as a
string, array or function value in C.

I accept that there are such things as string, array or function
declarations, and array or function types - but you can't do anything
with objects declared as such without converting them to pointers.
Except for sizeof, of course, but that really operates on types.

Seriously. Look at the standard in depth, and see.


Regards,
Nick Maclaren.
 
I

Ian Collins

Er, no. While I agree that I was over-simplifying, you have seriously
misunderstood C.

I very much doubt that Keith has misunderstood C!
It is NOT just when they are parameters, but any
time that they are used as values - there is no such thing as a
string, array or function value in C.

I accept that there are such things as string, array or function
declarations, and array or function types - but you can't do anything
with objects declared as such without converting them to pointers.
Except for sizeof, of course, but that really operates on types.

Eh?

int n = 42;
int x[1];
x[0] = n;

Where's the pointer?
 
S

Seebs

Er, no. While I agree that I was over-simplifying, you have seriously
misunderstood C. It is NOT just when they are parameters, but any
time that they are used as values - there is no such thing as a
string, array or function value in C.

I'm not quite sure of this. I agree that you can't do much with array
values, but struct assignment of a structure containing an array looks like
it does what you'd expect if you thought arrays had values.

-s
 
L

LR

Ian said:
Er, no. While I agree that I was over-simplifying, you have seriously
misunderstood C.

I very much doubt that Keith has misunderstood C!
It is NOT just when they are parameters, but any
time that they are used as values - there is no such thing as a
string, array or function value in C.

I accept that there are such things as string, array or function
declarations, and array or function types - but you can't do anything
with objects declared as such without converting them to pointers.
Except for sizeof, of course, but that really operates on types.

Eh?

int n = 42;
int x[1];
x[0] = n;

Where's the pointer?

This may be of interest.

http://c-faq.com/aryptr/aryptrequiv.html
"comp.lang.c FAQ list · Question 6.3"
"So what is meant by the ``equivalence of pointers and arrays'' in C?"

I tried this little snippet using c++, but I think it will compile in C
as well, maybe with some changes.

int n = 42;
int x[1];
int *p;

0[x] = n;
*(x+0) = n;

p = x;
p[0] = n;
0[p] = n;

char c = "abcd"[2]; /* c == 'c' */

LR
 
N

nmm1

I very much doubt that Keith has misunderstood C!

While I have a great deal of respect for Keith, from his postings,
I have not understood from them that he is an expert on the detailed
wording of the C standard. On this topic, look at:

6.3.2.1 Lvalues, arrays, and function designators

[#3] Except when it is the operand of the sizeof operator or
the unary & operator, or is a string literal used to
initialize an array, an expression that has type ``array of
type'' is converted to an expression with type ``pointer to
type'' that points to the initial element of the array
object and is not an lvalue. If the array object has
register storage class, the behavior is undefined.

[#4] A function designator is an expression that has
function type. Except when it is the operand of the sizeof
operator54) or the unary & operator, a function designator
with type ``function returning type'' is converted to an
expression that has type ``pointer to function returning
type''.

There are a hell of a lot of other references to look at, of course,
but the executive summary is that arrays (including strings) do not
last beyond translation phase 7, except as the pointers they have
been converted to and implicit bounds on the arithmetic permitted
on those pointers.

Similarly, functions become pointers in all contexts except actual
calls.
Eh?

int n = 42;
int x[1];
x[0] = n;

Where's the pointer?

6.5.2.1 Array subscripting

Constraints

[#1] One of the expressions shall have type ``pointer to
object type'', the other expression shall have integer type,
and the result has type ``type''.


Regards,
Nick Maclaren.
 
J

James Kuyper

I very much doubt that Keith has misunderstood C!

While I have a great deal of respect for Keith, from his postings,
I have not understood from them that he is an expert on the detailed
wording of the C standard. On this topic, look at:

6.3.2.1 Lvalues, arrays, and function designators

[#3] Except when it is the operand of the sizeof operator or
the unary& operator, or is a string literal used to
initialize an array, an expression that has type ``array of
type'' is converted to an expression with type ``pointer to
type'' that points to the initial element of the array
object and is not an lvalue. If the array object has
register storage class, the behavior is undefined.

[#4] A function designator is an expression that has
function type. Except when it is the operand of the sizeof
operator54) or the unary& operator, a function designator
with type ``function returning type'' is converted to an
expression that has type ``pointer to function returning
type''.

There are a hell of a lot of other references to look at, of course,
but the executive summary is that arrays (including strings) do not
last beyond translation phase 7, except as the pointers they have
been converted to and implicit bounds on the arithmetic permitted
on those pointers.

I'm quite sure that Keith is well aware of the factual content of that
paragraph.

You're talking about values, but strings, arrays, and functions are NOT
values in C. An array is an object, and a string is a data format.
Arrays don't even actually exist until the start of their lifetime,
during execution of the program, and they continue to exist until the
end of that lifetime. Strings don't exist until the required null
terminator value is stored, and cease to be strings when no longer so
terminated, all of which occurs during execution, If strings and arrays
disappeared in translation phase 7, then the corresponding pointers
would have nothing to point at.
Similarly, functions become pointers in all contexts except actual
calls.

Functions remain functions throughout the lifetime of the program, but
function identifiers in source code gets converted into pointers to the
corresponding function. If the function ceased to exist in translation
phase 7, the resulting pointer would have nothing to point at.
 
K

Keith Thompson

This followup is about C, but I've kept the wide cross-post for
now to make sure it's seen. Please consider redirecting further
followups to comp.lang.c if you want to discuss this further.
If you don't care about C, feel free to stop reading now; there is
no Fortran, PL/I, or numerical analysis content.

Er, no. While I agree that I was over-simplifying, you have seriously
misunderstood C.

It is NOT just when they are parameters, but any
time that they are used as values - there is no such thing as a
string, array or function value in C.

I accept that there are such things as string, array or function
declarations, and array or function types - but you can't do anything
with objects declared as such without converting them to pointers.
Except for sizeof, of course, but that really operates on types.

Seriously. Look at the standard in depth, and see.

I have looked at the standard in depth, and no, I haven't
misunderstood it.

A "string" is, by definition, "a contiguous sequence of characters
terminated by and including the first null character" (C99 7.1.1p1).
It's a data *layout*, not a data type. An array object may *contain*
a string at run time.

There's a tight relationship between arrays and pointers in C, but that
relationship absolutely is not identify. They are very different
things. An array type "describes a contiguously allocated nonempty set
of objects with a particular member object type, called the element
type" (C99 6.2.5p20); a pointer type "describes an object whose value
provides a reference to an entity of the referenced type" (same
paragraph).

There are several rules in C that tend to cause confusion in this area.

First, a parameter declaration of array type, such as
int foo(char arr[]);
is really a pointer declaration:
int foo(char *arr);
This isn't a run-time conversion, it's a compile-time adjustment.
For details, see C99 6.7.5.2p7.

Second, any expression of array type is implicitly converted to a
pointer to the array object's first element, with three exceptions.
This is a conversion, not an equivalence; it's an entirely separate
rule from the one for parameters, and applies in all expression
contexts. The exceptions are when the array expression is the
argument of a sizeof operator (sizeof arr yields the size of the
array, not the size of a pointer to the first element of the arrray),
when it's the argument of a unary "&" (address) operator (&arr yields
the address of the entire array, not of its first element; they're of
different types), and when it's a string literal in an initializer
used to initialize an object of array type (``char arr[10] = "hello";''
doesn't convert "hello" to an address). C99 6.3.2.1p3.

Section 6 of the comp.lang.c FAQ, <http://www.c-faq.com/> does a very
good job of explaining the relationship between C pointers and C arrays.

Similar rules apply to expressions of function type; see C99
6.3.2.1p4. Note that sizeof func, if func is a function name,
doesn't cause a conversion to pointer type, but in this case the
result is an error (constraint violation), since sizeof cannot
be applied to a function. A function call (which can be thought
of as an applicaton of the function call operator) requires a
pointer-to-function as its prefix. In most cases, this will be a
function name (an expression of function type) implicitly converted
to a pointer-to-function type.

Are there a string values? Maybe. There's no string type, but an array
object can contain a string. I don't think the standard uses the
term "string value".

Are there function values? No. There are expressions of function
type, but in most contexts they're immediately converted to pointers.

Are there array values? Absolutely. A "value" is the "precise
meaning of the contents of an object when interpreted as having a
specific type" (C99 3.17). For an array object, the value consists
of the values of all its elements. (Note that the standard's
definition of "value" is incomplete; it doesn't cover the value of
an expression, an unfortunate oversight IMHO.)

As I said, arrays and functions are almost always manipulated via
pointers (for arrays, it's usually a pointer to the first element
rather than a pointer to the entire array). Neither array types nor
pointer types are first-class, as they are in some other languages.
But they are types, and they are most definitely distinct from
pointer types (though the language sometimes seems to conspire to
obscure that distinction).

For example:

void print(char param[]) {
puts(param);
}
/* ... */
char s[6] = "Hello";
print(s);

The declaration of "param" is really a pointer declaration,
though the syntax makes it look like an array declaration; I could
equivalently have written ``void print(char *param)''. In the call
to print(), it *looks* like an array value is being passed to a
function that takes an array argument -- but in fact what's being
passed is a pointer to the array's first element (and the function
finds the end of the string by looking for the terminating null
character) -- or rather the puts function does that). Nevertheless,
there is a real array object called "s", and it contains an array
value consisting of 6 char values ('H', 'e', 'l', 'l', 'o', '\0').
And in the calls themselves, ``puts'' and ``print'' are expressions
of function type (the names of functions), but they're implicitly
converted to values of pointer-to-function type.

Strings are not pointers. Arrays are not pointers. Functions are not
pointers.
 
K

Keith Thompson

Ian Collins said:
Eh?

int n = 42;
int x[1];
x[0] = n;

Where's the pointer?

In ``x[0] = n'', the subexpression ``x'' is implicitly converted to
a pointer to the first (zeroth) element of the array x. So there's
a pointer *value*, but there's no pointer *object*.
 
K

Keith Thompson

I very much doubt that Keith has misunderstood C!

While I have a great deal of respect for Keith, from his postings,
I have not understood from them that he is an expert on the detailed
wording of the C standard. On this topic, look at:

6.3.2.1 Lvalues, arrays, and function designators

[#3] Except when it is the operand of the sizeof operator or
the unary & operator, or is a string literal used to
initialize an array, an expression that has type ``array of
type'' is converted to an expression with type ``pointer to
type'' that points to the initial element of the array
object and is not an lvalue. If the array object has
register storage class, the behavior is undefined.

[#4] A function designator is an expression that has
function type. Except when it is the operand of the sizeof
operator54) or the unary & operator, a function designator
with type ``function returning type'' is converted to an
expression that has type ``pointer to function returning
type''.

There are a hell of a lot of other references to look at, of course,
but the executive summary is that arrays (including strings) do not
last beyond translation phase 7, except as the pointers they have
been converted to and implicit bounds on the arithmetic permitted
on those pointers.

Array types, like any types, don't really exist after compilation.
Array objects do exist at run time, and they hold array values.

Any expression of array type is *converted* to a pointer to the array's
first element. This is conceptually a run-time operation, though it's
almost certainly handled at compile time.

As I explained in my other followup, there are array values (see the
standard's definition of "value" in 3.17); it's just somewhat unusual to
manipulate them as values.

But as Seebs pointed out, a struct may contain an array member, which
may be assigned as part of assigning the struct value:

struct foo {
int arr[10];
};
struct foo sf1 = { 0 };
struct foo sf2;
sf2 = sf1;
Similarly, functions become pointers in all contexts except actual
calls.

Functions don't *become* pointers. Expressions of function type are
*converted* to pointer values.
Eh?

int n = 42;
int x[1];
x[0] = n;

Where's the pointer?

6.5.2.1 Array subscripting

Constraints

[#1] One of the expressions shall have type ``pointer to
object type'', the other expression shall have integer type,
and the result has type ``type''.

Right. A pointer value is created by the conversion, but there's no
pointer object. (The unqualified word "pointer" is ambiguous; I
generally try to refer to pointer types, pointer objects, and pointer
values explicitly. Likewise for arrays.)
 
A

aruzinsky

No, it isn't.


There are tons of algorithms which are elegant and clear using pointers,
and hard to write clearly at all without them.  Perhaps you should just
practice more until pointers are more comfortable for you.

-s

Here is an example of C++ source using array pointers that I wrote:

float sum, *xx, *px, *cx;
for (xx=x,j=0;j<mn;j++,xx++)
{
for (sum=0, i=psfsm, cx=&c(psfs.ip[j]), px=psfs.z[j]; i; i--, cx++,
px++) sum += *px * *cx;
*xx = sum;
}

No sane person would want to see such constructs in Numerical Recipes.
 
J

Jens Thoms Toerring

Here is an example of C++ source using array pointers that I wrote:
float sum, *xx, *px, *cx;
for (xx=x,j=0;j<mn;j++,xx++)
{
for (sum=0, i=psfsm, cx=&c(psfs.ip[j]), px=psfs.z[j]; i; i--, cx++,
px++) sum += *px * *cx;
*xx = sum;
}
No sane person would want to see such constructs in Numerical Recipes.

Well, no same person would write code like that;-) Being able
to write obfuscated code is not necessarily an argument against
using pointers. With that argument all languages that allow to
write unreadable code would be out. And then hardly any would
be left. But there's no reason to write obfuscated code, on the
contrary, it may keep the compiler from optimizing properly.

Even if you just take the code a bit apart, without even giving
the identifiers any more meaningful names, like in

float *xx = x;

for ( j = 0; j < mn; j++ )
{
float sum = 0.0,
* cx = &c( psfs.ip[ j ] ),
* px = psfs.z[ j ];

for ( i = 0; i < psfsm; i++ )
sum += *px++ * *cx++;

*xx++ = sum;
}

it already looks a bit more accessible without doing
anything that might slow the program down. That mostly
looks like the common idiom for calculating the scalar
product of two vectors. But one starts to wonder if ha-
ving the c() function return a float value makes sense -
that isn't an lvalue, so taking the address looks fishy
indeed. Is 'c' some convoluted macro?

When that is resolved and you then change the identifier
names to something reasonable (i.e. all but 'i', 'j' and
'sum') you will have code which, despite using pointers,
any C or C++ programmer worth its salt should be able to
grasp at a glance or two without too many problems.

Regards, Jens
 
U

Uno

No, it isn't.


There are tons of algorithms which are elegant and clear using pointers,
and hard to write clearly at all without them. Perhaps you should just
practice more until pointers are more comfortable for you.

Examples?
 
S

Seebs

Here is an example of C++ source using array pointers that I wrote:
float sum, *xx, *px, *cx;
for (xx=x,j=0;j<mn;j++,xx++)
{
for (sum=0, i=psfsm, cx=&c(psfs.ip[j]), px=psfs.z[j]; i; i--, cx++,
px++) sum += *px * *cx;
*xx = sum;
}

That is truly awful code.
No sane person would want to see such constructs in Numerical Recipes.

Straw man. The claim made was not that every possible program that used
pointers would be a good or clear one, but that pointers are a good way
to express code.

If you wrote code like this for any purpose other than with intent to
show off how unreadable you could make it, you should not be writing code
for didactic purposes at all.

I need a thing to entertain me, so let's have some fun with this.

float sum, *xx, *px, *cx;
for (xx=x,j=0;j<mn;j++,xx++) {
for (sum=0, i=psfsm, cx=&c(psfs.ip[j]), px=psfs.z[j]; i; i--, cx++, px++)
sum += *px * *cx;
*xx = sum;
}

Let's see. We don't see declarations for sum, i, j, c, x, psfs. We can
infer that sum is probably a float, i and j are ints, mn is an int, x is an
array of floats, and that psfs.z[j] is an array of arrays of floats. Your
use of c is just plain wrong in C -- you're calling a function, and then
trying to take the address of the return value. Unless c is a macro.

Having no clue what the &c() is supposed to be doing, let's just pretend that
it's nugatory and pretend that ip and z are arrays-of-pointers-to-float.

int
do_something(float *x, int max1, int max2, float **ip, float **z) {
int i, j;
float sum;
float *xx, *px, *cx;
xx = x;
for (j = 0; j < max1; ++j) {
sum = 0;
cx = ip[j];
px = z[j];
for (i = max2; i; --i) {
sum += *px++ * *cx++;
}
*xx++ = sum;
}
}

So, what this actually does is loop max1 times counting up, pick the nth
elements of two things, which are themselves arrays, then loop through them
max2 times counting down, summing them, and store the result. This looks
suspiciously like trying to calculate a dot product. This can be
further-simplified in a few obvious ways, but whatever.

The problem here is not "using pointers". The problem here is writing
shitty code. There is *no* reason to be combining all these unrelated
bits into the components of the for loop. It's not at all obvious
that counting backwards for the i loop instead of forwards is buying
you anything, least of all intentionally.

In short, this offers the reader a compelling argument, not against using
pointers in code intended for teaching or in illustration, but against
trusting your judgement on anything whatsoever having to do with programming.

-s
 
A

aruzinsky

I much rather
read C source code written to resemble pseudo-code.  Afterwards, it is
easy enough for me to implement pointers (which later I have
difficulty reading).
There are tons of algorithms which are elegant and clear using pointers,
and hard to write clearly at all without them.  Perhaps you should just
practice more until pointers are more comfortable for you.
Here is an example of C++ source using array pointers that I wrote:
float sum, *xx, *px, *cx;
for (xx=x,j=0;j<mn;j++,xx++)
{
   for (sum=0, i=psfsm, cx=&c(psfs.ip[j]), px=psfs.z[j]; i; i--, cx++,
px++) sum += *px * *cx;
   *xx = sum;
}
No sane person would want to see such constructs in Numerical Recipes.

Well, no same person would write code like that;-) Being able
to write obfuscated code is not necessarily an argument against
using pointers. With that argument all languages that allow to
write unreadable code would be out. And then hardly any would
be left. But there's no reason to write obfuscated code, on the
contrary, it may keep the compiler from optimizing properly.

Even if you just take the code a bit apart, without even giving
the identifiers any more meaningful names, like in

float *xx = x;

for ( j = 0; j < mn; j++ )
{
    float   sum = 0.0,
          * cx  = &c( psfs.ip[ j ] ),
          * px  = psfs.z[ j ];

    for ( i = 0; i < psfsm; i++ )
        sum += *px++ * *cx++;

    *xx++ = sum;

}

it already looks a bit more accessible without doing
anything that might slow the program down. That mostly
looks like the common idiom for calculating the scalar
product of two vectors. But one starts to wonder if ha-
ving the c() function return a float value makes sense -
that isn't an lvalue, so taking the address looks fishy
indeed. Is 'c' some convoluted macro?

When that is resolved and you then change the identifier
names to something reasonable (i.e. all but 'i', 'j' and
'sum') you will have code which, despite using pointers,
any C or C++ programmer worth its salt should be able to
grasp at a glance or two without too many problems.

                      Regards, Jens
--
  \   Jens Thoms Toerring  ___      (e-mail address removed)
   \__________________________      http://toerring.de- Hide quoted text -

- Show quoted text -

1. "it already looks a bit more accessible without doing anything that
might slow the program down." - Speak for yourself; it looks more
accessible to you because you have been brainwashed into accepting the
absurdities of programmer culture. The practice of initializing and
incrementing pointers separately from loop counters is moronic. They
should both be put in the for statement because loop counters and
pointers are more the same than not. If fact, a pointer can be used
as a loop counter. So, then where do you put the pointer
initialization and increment? Thusly, most people who have not
previously been brainwashed into accepting the absurdities of
programmer cultural would find my version more readable.

2. "Is 'c' some convoluted macro?" - No. Since I told you that my
code was C++, you should have guessed that c is instantiation of a
class for allocating floating point arrays on the heap and c(int) and
c(int,int) are inline member functions for accessing an element of an
array by indices. BTW, I don't want to see classes in Numerical
Recipes either.

To Others:

Everyone who wants to see or not see Jens Thoms Toerring's version of
pointer use in Numerical Recipes, please, vote.
 
S

Seebs

1. "it already looks a bit more accessible without doing anything that
might slow the program down." - Speak for yourself; it looks more
accessible to you because you have been brainwashed into accepting the
absurdities of programmer culture.

Uh...

So, basically, your argument is:

1. Your code is illegible to you.
2. People who can read their own code have been "brainwashed".
The practice of initializing and
incrementing pointers separately from loop counters is moronic. They
should both be put in the for statement because loop counters and
pointers are more the same than not.

Your dogma produces code you yourself think is illegible. Your dogma is
stupid.
2. "Is 'c' some convoluted macro?" - No. Since I told you that my
code was C++, you should have guessed that c is instantiation of a
class for allocating floating point arrays on the heap and c(int) and
c(int,int) are inline member functions for accessing an element of an
array by indices. BTW, I don't want to see classes in Numerical
Recipes either.

Then don't use them badly.
To Others:
Everyone who wants to see or not see Jens Thoms Toerring's version of
pointer use in Numerical Recipes, please, vote.

With the possible exception of "Bill Cunningham", and maybe one or two
of the people who explicitly identify themselves as trolling the newsgroup,
there is not any programmer I've ever dealt with whose code I would not
prefer to the monstrosity you offered as an example of pointer usage.

You do not understand the essential nature of writing code, which is that
it should be about clear communication. If you start making up rules like
"loop counters and pointers are more the same than not" and the resulting
code is illegible, *the rule is wrong*.

Communication is not a discipline suited to ivory-tower intellectualism.
Try it. If you produce something that you and other people find clear
and legible, then you've done a good job. If you yourself think it's
illegible, you've done a bad job, no matter how much you think it made
sense in theory.

Also, *plonk*.

-s
 
A

aruzinsky

I much rather
read C source code written to resemble pseudo-code. ?Afterwards, it is
easy enough for me to implement pointers (which later I have
difficulty reading).
There are tons of algorithms which are elegant and clear using pointers,
and hard to write clearly at all without them. ?Perhaps you should just
practice more until pointers are more comfortable for you.
Here is an example of C++ source using array pointers that I wrote:
float sum, *xx, *px, *cx;
for (xx=x,j=0;j<mn;j++,xx++)
{
   for (sum=0, i=psfsm, cx=&c(psfs.ip[j]), px=psfs.z[j]; i; i--, cx++,
px++) sum += *px * *cx;
   *xx = sum;
}

That is truly awful code.
No sane person would want to see such constructs in Numerical Recipes.

Straw man.  The claim made was not that every possible program that used
pointers would be a good or clear one, but that pointers are a good way
to express code.

Bad grammar. "Pointers" are not a "way" and the bare plural,
"pointers," is of unknown quantitity therefore I don't know what you
are talking about nor have you provided examples to clarify what you
are talking about. I merely gave an example of the kind of speed
efficient pointer usage that I don't want to see in Numerical Recipes,
whereas, you failed to give any example of the kind of pointer usage
that you want to see in Numerical Recipes. If I knew what you were
talking about, I might even agree with you.
If you wrote code like this for any purpose other than with intent to
show off how unreadable you could make it, you should not be writing code
for didactic purposes at all.

I never suggested that it was didactic. I suggested that it was
relatively unreadable.
I need a thing to entertain me, so let's have some fun with this.

float sum, *xx, *px, *cx;
for (xx=x,j=0;j<mn;j++,xx++) {
    for (sum=0, i=psfsm, cx=&c(psfs.ip[j]), px=psfs.z[j]; i; i--, cx++, px++)
        sum += *px * *cx;
    *xx = sum;

}

Let's see.  We don't see declarations for sum, i, j, c, x, psfs.  We can
infer that sum is probably a float, i and j are ints, mn is an int, x is an
array of floats, and that psfs.z[j] is an array of arrays of floats.  Your
use of c is just plain wrong in C -- you're calling a function, and then
trying to take the address of the return value.  Unless c is a macro.

Having no clue what the &c() is supposed to be doing, let's just pretend that

But, you do have a clue. I told you that it was C++.
it's nugatory and pretend that IPA and z are arrays-of-pointers-to-float.

        int
        do_something(float *x, int Max, int Max, float **IPA, float **z) {
                int i, j;
                float sum;
                float *xx, *PX, *CZ;
                xx = x;
                for (j = 0; j < Max; ++j) {
                        sum = 0;
                        CZ = IPA[j];
                        PX = z[j];
                        for (i = Max; i; --i) {
                                sum += *PX++ * *CZ++;
                        }
                        *xx++ = sum;
                }
        }

So, what this actually does is loop Max times counting up, pick the nth
elements of two things, which are themselves arrays, then loop through them
Max times counting down, summing them, and store the result.  This looks
suspiciously like trying to calculate a dot product.  This can be
further-simplified in a few obvious ways, but whatever.

You should have started with "whatever."
The problem here is not "using pointers".  The problem here is writing
shitty code.  There is *no* reason to be combining all these unrelated
bits into the components of the for loop.

There's no reason not to. Typically, nobody but me and my compiler
reads my code. Thus, the only criterion for "shitty" is program speed
which you have not addressed.
 It's not at all obvious
that counting back wards for the i loop instead of for wards is buying
you anything, least of all intentionally.

It depends on the compiler and CPU.
In short, this offers the reader a compelling argument, not against using
pointers in code intended for teaching or in illustration, but against
trusting your judgment on anything whatsoever having to do with programming.

No, your comment shows bad judgment because my code when written was
intended to be read by nobody but myself and my compiler. I presented
an excerpt here to demonstrate relatively unreadable code and
succeeded. Unless you have a valid criticism based on program speed,
your criticism is stupid.
 
J

Jens Thoms Toerring

In comp.lang.c aruzinsky said:
1. "it already looks a bit more accessible without doing anything that
might slow the program down." - Speak for yourself; it looks more
accessible to you because you have been brainwashed into accepting the
absurdities of programmer culture. The practice of initializing and
incrementing pointers separately from loop counters is moronic.

I don't see writing easy to read code as "moronic" or being
"brainwashed", sorry - I sometimes have to go back and figure
out what I did myself and have found that not putting too many
things into a single construct helps a lot as does following
certain common idioms I saw in a lot of code that was relati-
vely easy to understand. And you yourself admitted that you
have problems understanding your own code. Perhaps there's
some tiny chance that this has to do with the code not being
that well-written instead of just being due to the use of
pointers?
They
should both be put in the for statement because loop counters and
pointers are more the same than not. If fact, a pointer can be used
as a loop counter. So, then where do you put the pointer
initialization and increment? Thusly, most people who have not
previously been brainwashed into accepting the absurdities of
programmer cultural would find my version more readable.

Suit yourself as long as I don't have to deal with your code
on a regular basis...
2. "Is 'c' some convoluted macro?" - No. Since I told you that my
code was C++, you should have guessed that c is instantiation of a
class for allocating floating point arrays on the heap and c(int) and
c(int,int) are inline member functions for accessing an element of an
array by indices.

I may not be too good at C++ but when c(int) (let's assume
int was the type of the argument) is, as you say, for acces-
sing an element of an array, which probably means that it is
returning a float value element of that array (or what means
"accessing" in this context?), how does taking the address of
that (or any) return value makes sense, may it be C or C++?
Or have you somehow managed to overload the '&' operator for
floats? Sorry that I made the assumption that this was meant
as an example for the difficulties of writing readable code
using pointers, not of using some arcane features of C++ in
a discussion about the C version of Numerical Recipes.
BTW, I don't want to see classes in Numerical
Recipes either.

Agreed, at least not in a C version of Numerical Recipes.
In a C++ version of the book I wouldn't mind at all.
 
A

aruzinsky

Uh...

So, basically, your argument is:

1.  Your code is illegible to you.

No, I said "difficulty reading" and "relatively unreadable."
2.  People who can read their own code have been "brainwashed".

No, I said that you were brainwashed.
Your dogma produces code you yourself think is illegible.  Your dogma is
stupid.

No, I said "difficulty reading" and "relatively unreadable."

Then don't use them badly.

My computer doesn't complain.
With the possible exception of "Bill Cunningham", and maybe one or two
of the people who explicitly identify themselves as trolling the newsgroup,
there is not any programmer I've ever dealt with whose code I would not
prefer to the monstrosity you offered as an example of pointer usage.

But, I presented this code as an example of relatively unreadable code
and succeeded. And, it works on my computer just fine, so, you have
no grounds for complaint.
You do not understand the essential nature of writing code, which is that
it should be about clear communication.  

No you don't. It is about clear communication to the compiler,
computer, one's self, and other people with decreasing importance in
that order.
If you start making up rules like
"loop counters and pointers are more the same than not" and the resulting
code is illegible, *the rule is wrong*.

I said "difficulty reading" and "relatively unreadable."
Communication is not a discipline suited to ivory-tower intellectualism.
Try it.  If you produce something that you and other people find clear
and legible, then you've done a good job.  If you yourself think it's
illegible, you've done a bad job, no matter how much you think it made
sense in theory.

Bullshit. The programming language, Forth, has a well known reputation
for being a "write only" language.
Also, *plonk*.

Then you won't mind when I call you an "idiot" behind your back.
 
A

aruzinsky

I don't see writing easy to read code as "moronic" or being
"brainwashed",

1. I find your pointer code more difficult to read than mine.

2. I find array indexing easier to read than my pointer code.

3. I can convert to pointers with little effort or difficulty and do
so only to increase speed.

4. The compiler doesn't care.
sorry - I sometimes have to go back and figure
out what I did myself and have found that not putting too many
things into a single construct helps a lot as does following
certain common idioms I saw in a lot of code that was relati-
vely easy to understand. And you yourself admitted that you
have problems understanding your own code. Perhaps there's
some tiny chance that this has to do with the code not being
that well-written instead of just being due to the use of
pointers?

No, there usually are tradeoffs between human readability, speed and
RAM usage.

In C++, the construct for a pointer to a member function is such that
it is as though it were designed to be unreadable and unwritable,
e.g., matrix& (matrix::*A)(matrix&). But, there are good reasons to
use those pointers. What would you say to person on the C++ committe
responsible for that?
Suit yourself as long as I don't have to deal with your code
on a regular basis...

Ditto.


I may not be too good at C++ but when c(int) (let's assume
int was the type of the argument) is, as you say, for acces-
sing an element of an array, which probably means that it is
returning a float value element of that array (or what means
"accessing" in this context?), how does taking the address of
that (or any) return value makes sense, may it be C or C++?

I don't understand your question. It has been decades since I wrote
in C. Refresh my memory, does C have "&" whereby the address of x
is gotten with &x? If not, how do you get the address? It is also
used for bitwise and, which, of course is a completely different
operation.
Or have you somehow managed to overload the '&' operator for
floats?

No, & works on all data types. But, getting back to c(i), it behaves
like a macro for c.x where the array x[] is a member of class c.
c(i,j) behaves like a macro for c.z[j] where z[] is an array of
pointers such that x can be quickly accessed as two dimensional.
Thus, the same array can be treated as one or two dimensional.
Sorry that I made the assumption that this was meant
as an example for the difficulties of writing readable code
using pointers, not of using some arcane features of C++ in
a discussion about the C version of Numerical Recipes.

Maybe, my bad, but I don't want to see C++ in Numerical Recipes even
more.
Agreed, at least not in a C version of Numerical Recipes.
In a C++ version of the book I wouldn't mind at all.

Communicating numerical algorithms to other people in C++ is typically
worse in practice.
 
U

Uno

Everyone who wants to see or not see Jens Thoms Toerring's version of
pointer use in Numerical Recipes, please, vote.

I heard it's already in pre-production. Seebs is going to write a
chapter called

§42. Calculating Pi with Pointers.

He'll break the record for this endeavor with 200 digits.

The appendix will be filled with the "tons of" good numerical recipes
he's whipped up with pointers.

How about those Auburn Tigers, holy smokes?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top