Hi all
I am currently exploring the world of pointers and have encounter some
inconsistent information regarding the best way to reference an
array: array[1] OR *(array +1).
One book says that you should not use the syntax array[1] because
of performance reason. Another book says that the syntax array[1] is
only used by FORTRAN programmers who do not understand c pointers. So
what is the true oh wizards? Does it make a difference?
Thanks Peter
|
|
0
|
|
|
|
Reply
|
pc722 (3)
|
2/7/2012 9:28:17 PM |
|
peter <pc722@nospam.mail.com.br> writes:
>I am currently exploring the world of pointers and have encounter some
>inconsistent information regarding the best way to reference an
>array: array[1] OR *(array +1).
�*� is the opposite of a �reference�, it is a /de/reference.
�[]� is an abbreviation, so it should be preferred when shorter.
>One book says that you should not use the syntax array[1] because
>of performance reason.
I do not believe this.
>Another book says that the syntax array[1] is only used by
>FORTRAN programmers who do not understand c pointers.
I do not believe this.
|
|
0
|
|
|
|
Reply
|
ram (2827)
|
2/7/2012 9:31:18 PM
|
|
peter <pc722@nospam.mail.com.br> wrote:
> Hi all
> I am currently exploring the world of pointers and have encounter some
> inconsistent information regarding the best way to reference an
> array: array[1] OR *(array +1).
Your examples below aren't really inconsistent. The rationales are
inconsistent, but they both appear to prefer explicit pointer arithmetic
over array notation.
> One book says that you should not use the syntax array[1] because
> of performance reason. Another book says that the syntax array[1] is
> only used by FORTRAN programmers who do not understand c pointers. So
> what is the true oh wizards? Does it make a difference?
Can you provide citations? Those rationales are so far out there that I'm
rather skeptical of what you're saying.
The general consensus is that array notation is perfectly okay, particularly
when you're dealing with arrays.
|
|
0
|
|
|
|
Reply
|
William
|
2/7/2012 9:50:55 PM
|
|
On 02/07/2012 04:28 PM, peter wrote:
> Hi all
>
> I am currently exploring the world of pointers and have encounter some
> inconsistent information regarding the best way to reference an
> array: array[1] OR *(array +1).
>
> One book says that you should not use the syntax array[1] because
> of performance reason. Another book says that the syntax array[1] is
> only used by FORTRAN programmers who do not understand c pointers. So
> what is the true oh wizards? Does it make a difference?
Burn both books - they're both telling you nonsense. If you can't afford
to do that, then sell them to somebody, but realize that you may be
ruining the career of any one who makes the mistake of learning C from
those books.
By definition, the behavior of array[1] is EXACTLY equivalent to
*(array+1); any compiler which generates different code for the
different expressions is not very well designed. array[1] takes one less
character to type, and that character is a shifted one. Far more
important is that, IMO, it's usually easier to read and understand. The
other syntax occurs only in only a few cases in the body of code I'm
currently responsible for, and only in code written by someone else.
However, if you run into a context where *(array+1) makes your code
easier to read and understand, don't hesitate to use it.
|
|
0
|
|
|
|
Reply
|
jameskuyper (5157)
|
2/7/2012 10:13:52 PM
|
|
On 07-Feb-12 15:28, peter wrote:
> I am currently exploring the world of pointers and have encounter some
> inconsistent information regarding the best way to reference an
> array: array[1] OR *(array +1).
What is "best" depends on what you're measuring, and you don't specify.
IMHO, the most important thing in nearly all cases is clarity of code,
and array notation is usually better for that, though you may find
exceptions now and then.
> One book says that you should not use the syntax array[1] because
> of performance reason. Another book says that the syntax array[1] is
> only used by FORTRAN programmers who do not understand c pointers. So
> what is the true oh wizards? Does it make a difference?
It sounds like you need better books.
With modern compilers, array notation should result in code that is _at
least_ as good as pointer notation. It can result in _better_ code, in
some cases, if it allows the compiler to make more aggressive
optimizations due to not having to worry about aliasing.
S
--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
|
|
0
|
|
|
|
Reply
|
stephen (1125)
|
2/7/2012 10:38:39 PM
|
|
peter <pc722@nospam.mail.com.br> writes:
> I am currently exploring the world of pointers and have encounter some
> inconsistent information regarding the best way to reference an
> array: array[1] OR *(array +1).
array[1] is *by definition* equivalent to *(array+1).
> One book says that you should not use the syntax array[1] because
> of performance reason. Another book says that the syntax array[1] is
> only used by FORTRAN programmers who do not understand c pointers. So
> what is the true oh wizards? Does it make a difference?
Both books either are quite old, or were written by an author who
doesn't really know what he's talking about. Use whichever form
more clearly expresses what you're doing, and let the compiler
worry about generating decent code.
Once upon a time, the advice might have made some sense. But these
days, compilers are likely to generate equally good code for either
form (as long as you specify an optimization option like "-O3").
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
kst-u (21469)
|
2/7/2012 10:41:25 PM
|
|
Keith Thompson <kst-u@mib.org> writes:
>array[1] is *by definition* equivalent to *(array+1).
#include <stdio.h> // printf
int main( void )
{ int b[] ={ 234, 567 }; int * array[ 2 ]={ 0, b };
printf( "%d\n", array[1] [ 1 ]);
printf( "%d\n", *(array+1) [ 1 ]); }
|
|
0
|
|
|
|
Reply
|
ram (2827)
|
2/7/2012 10:54:26 PM
|
|
On Feb 7, 9:28=A0pm, peter <pc...@nospam.mail.com.br> wrote:
> I am currently exploring the world of pointers and have encounter some
> inconsistent information regarding the best way to reference an
> array: array[1] =A0 OR =A0 =A0*(array +1).
You should use whichever is clearest. If the thing really is an array,
then the clearest way will usually be array[1].
> One book says that you should not use the syntax array[1] because
> of performance reason.
As others have said, this seems highly unlikely for the example you
have given above. What the book may be recommending is that you use a
pointer to step though the array. For example, replacing:
int x;
for (x =3D 0; array[x]; x++) dostuff(array[x]);
with
type *p;
for (p =3D array; *p; p++) dostuff(*p);
The latter might be slightly quicker, but it's not likely to make too
much difference.
> Another book says that the syntax array[1] is
> only used by FORTRAN programmers who do not understand c pointers.
Possibly what the book is trying to say is that, if you want your
array to store ten values, a proper C programmer will do:
type array[10];
and will use the values from array[0] to array[9]. Someone who is more
used to another language might do:
type array[11];
and use the values from array[1] to array[10]. This wastes the space
used for array[0], and means you have to remember to allocate an array
one bigger than what you actually want.
Hope this helps.
Paul.
|
|
0
|
|
|
|
Reply
|
gw7rib (462)
|
2/7/2012 10:55:53 PM
|
|
ram@zedat.fu-berlin.de (Stefan Ram) writes:
> Keith Thompson <kst-u@mib.org> writes:
>>array[1] is *by definition* equivalent to *(array+1).
>
> #include <stdio.h> // printf
>
> int main( void )
> { int b[] ={ 234, 567 }; int * array[ 2 ]={ 0, b };
> printf( "%d\n", array[1] [ 1 ]);
> printf( "%d\n", *(array+1) [ 1 ]); }
*sigh* Must "equivalent" mean "can be lexically replaced by"? Has
c.l.c become a place where "a+b is equivalent to b+a" must be
challenged?
--
Ben.
|
|
0
|
|
|
|
Reply
|
ben.usenet (6515)
|
2/7/2012 11:07:02 PM
|
|
Stephen Sprunk <stephen@sprunk.org> writes:
> On 07-Feb-12 15:28, peter wrote:
<snip>
>> One book says that you should not use the syntax array[1] because
>> of performance reason. Another book says that the syntax array[1] is
>> only used by FORTRAN programmers who do not understand c pointers. So
>> what is the true oh wizards? Does it make a difference?
>
> It sounds like you need better books.
I agree, but I am saddened by the number of daft remarks attributed to
books without a citation.
Peter: please name these books. The world needs to know who is saying
such things.
<snip>
--
Ben.
|
|
0
|
|
|
|
Reply
|
ben.usenet (6515)
|
2/7/2012 11:09:57 PM
|
|
On 2/7/2012 16:28, peter wrote:
> Hi all
>
> I am currently exploring the world of pointers and have encounter some
> inconsistent information regarding the best way to reference an
> array: array[1] OR *(array +1).
>
The expression:
E1[E2]
is defined to be semantically identical to:
(*((E1) + (E2)))
So your example 'array[1]' is identical to '(*((array) + (1)))'. After
removing some of those brackets, we get '*(array + 1)', which is just
the alternative you are concerned about.
> One book says that you should not use the syntax array[1] because
> of performance reason. Another book says that the syntax array[1] is
> only used by FORTRAN programmers who do not understand c pointers. So
> what is the true oh wizards? Does it make a difference?
Which books are those?
Did either of them mention doing:
1[array]
? It's just as valid, and actually comes in handy in at least one
particular case:
#define CountOf(array_) (sizeof (array_) / sizeof *(array_))
int (* ptr_to_array)[42];
ptr_to_array = malloc(sizeof *ptr_to_array);
if (ptr_to_array) {
int i;
/* Assign '13' to each element */
for (i = 0; i < CountOf(*ptr_to_array); ++i)
i[*ptr_to_array] = 13;
/*
* Versus the following, which is slightly
* more typing, but probably clearer
*/
(*ptr_to_array)[i] = 13;
}
|
|
0
|
|
|
|
Reply
|
sha0.miller (876)
|
2/7/2012 11:11:36 PM
|
|
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>Must "equivalent" mean "can be lexically replaced by"?
No, it's ambigous. It might mean this or something else.
When James writes:
|array[1] takes one less character to type
we are indeed comparing expressions, not their values.
|
|
0
|
|
|
|
Reply
|
ram (2827)
|
2/7/2012 11:12:33 PM
|
|
On 2/7/2012 17:54, Stefan Ram wrote:
> Keith Thompson<kst-u@mib.org> writes:
>> array[1] is *by definition* equivalent to *(array+1).
>
> #include<stdio.h> // printf
>
> int main( void )
> { int b[] ={ 234, 567 }; int * array[ 2 ]={ 0, b };
> printf( "%d\n", array[1] [ 1 ]);
> printf( "%d\n", *(array+1) [ 1 ]);
return 0;
> }
I had to, though it was 100% correct and 0% helpful. Sorry about that. :)
|
|
0
|
|
|
|
Reply
|
sha0.miller (876)
|
2/7/2012 11:21:24 PM
|
|
On 2012-02-07, Stefan Ram <ram@zedat.fu-berlin.de> wrote:
> Keith Thompson <kst-u@mib.org> writes:
>>array[1] is *by definition* equivalent to *(array+1).
>
> #include <stdio.h> // printf
>
> int main( void )
> { int b[] ={ 234, 567 }; int * array[ 2 ]={ 0, b };
> printf( "%d\n", array[1] [ 1 ]);
> printf( "%d\n", *(array+1) [ 1 ]); }
You forgot something. Try
printf( "%d\n", ( array[1] ) [ 1 ]);
printf( "%d\n", ( *(array+1) ) [ 1 ]); }
|
|
0
|
|
|
|
Reply
|
ike8 (164)
|
2/7/2012 11:36:09 PM
|
|
On 02/07/2012 06:12 PM, Stefan Ram wrote:
> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>> Must "equivalent" mean "can be lexically replaced by"?
>
> No, it's ambigous. It might mean this or something else.
>
> When James writes:
>
> |array[1] takes one less character to type
>
> we are indeed comparing expressions, not their values.
Correct - in the context that you brought up, it saves three characters,
all shifted, and not just one.
|
|
0
|
|
|
|
Reply
|
jameskuyper (5157)
|
2/8/2012 12:14:59 AM
|
|
ram@zedat.fu-berlin.de (Stefan Ram) writes:
> Keith Thompson <kst-u@mib.org> writes:
>>array[1] is *by definition* equivalent to *(array+1).
>
> #include <stdio.h> // printf
>
> int main( void )
> { int b[] ={ 234, 567 }; int * array[ 2 ]={ 0, b };
> printf( "%d\n", array[1] [ 1 ]);
> printf( "%d\n", *(array+1) [ 1 ]); }
Ok, quoting the standard (C99 6.5.2.1p2):
The definition of the subscript operator [] is that E1[E2] is
identical to (*((E1)+(E2))).
It was slightly sloppy of me to omit the parentheses.
(BTW, I find your compressed code layout difficult to read.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
kst-u (21469)
|
2/8/2012 12:24:28 AM
|
|
Shao Miller <sha0.miller@gmail.com> writes:
> On 2/7/2012 17:54, Stefan Ram wrote:
>> Keith Thompson<kst-u@mib.org> writes:
>>> array[1] is *by definition* equivalent to *(array+1).
>>
>> #include<stdio.h> // printf
>>
>> int main( void )
>> { int b[] ={ 234, 567 }; int * array[ 2 ]={ 0, b };
>> printf( "%d\n", array[1] [ 1 ]);
>> printf( "%d\n", *(array+1) [ 1 ]);
> return 0;
>> }
>
> I had to, though it was 100% correct and 0% helpful. Sorry about that. :)
C does not require a "return 0;" at the end of main(), as of the current
standard or the one preceding it.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
kst-u (21469)
|
2/8/2012 12:25:51 AM
|
|
Ike Naar <ike@sverige.freeshell.org> writes:
> On 2012-02-07, Stefan Ram <ram@zedat.fu-berlin.de> wrote:
>> Keith Thompson <kst-u@mib.org> writes:
>>>array[1] is *by definition* equivalent to *(array+1).
>>
>> #include <stdio.h> // printf
>>
>> int main( void )
>> { int b[] ={ 234, 567 }; int * array[ 2 ]={ 0, b };
>> printf( "%d\n", array[1] [ 1 ]);
>> printf( "%d\n", *(array+1) [ 1 ]); }
>
> You forgot something. Try
>
> printf( "%d\n", ( array[1] ) [ 1 ]);
> printf( "%d\n", ( *(array+1) ) [ 1 ]); }
I don't believe he "forgot" anything. (In fact, I did.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
kst-u (21469)
|
2/8/2012 12:26:14 AM
|
|
On 2/7/2012 19:25, Keith Thompson wrote:
> Shao Miller<sha0.miller@gmail.com> writes:
>> On 2/7/2012 17:54, Stefan Ram wrote:
>>> Keith Thompson<kst-u@mib.org> writes:
>>>> array[1] is *by definition* equivalent to *(array+1).
>>>
>>> #include<stdio.h> // printf
>>>
>>> int main( void )
>>> { int b[] ={ 234, 567 }; int * array[ 2 ]={ 0, b };
>>> printf( "%d\n", array[1] [ 1 ]);
>>> printf( "%d\n", *(array+1) [ 1 ]);
>> return 0;
>>> }
>>
>> I had to, though it was 100% correct and 0% helpful. Sorry about that. :)
>
> C does not require a "return 0;" at the end of main(), as of the current
> standard or the one preceding it.
>
I hope you're joking. Mine was a joke. :) No "requirement" was
claimed. I hoped to add something valuable, just as Mr. Stefan Ram did
for you (other than from Ben's perspective, that is).
|
|
0
|
|
|
|
Reply
|
sha0.miller (876)
|
2/8/2012 1:31:57 AM
|
|
On Feb 7, 3:28=A0pm, peter <pc...@nospam.mail.com.br> wrote:
> Hi all
>
> I am currently exploring the world of pointers and have encounter some
> inconsistent information regarding the best way to reference an
> array: array[1] =A0 OR =A0 =A0*(array +1).
>
> One book says that you should not use the syntax array[1] because
> of performance reason. Another book says that the syntax array[1] is
> only used by FORTRAN programmers who do not understand c pointers. So
> what is the true oh wizards? Does it make a difference?
>
> Thanks Peter
Out of curiosity, which books are these?
FWIW, subscript notation *may* result in a few more instructions at
the assembly level than pointer notation. Here are some examples
compiled with gcc -g -Wa,aldh:
First, indexing with a constant expression:
14:init.c **** y =3D x[5];
210 .LM5:
211 0025 8B45DC movl -36(%ebp), %eax
212 0028 8945C4 movl %eax, -60(%ebp)
15:init.c **** y =3D *(x + 5);
214 .LM6:
215 002b 8B45DC movl -36(%ebp), %eax
216 002e 8945C4 movl %eax, -60(%ebp)
No difference; the same number of instructions are generated.
Indexing with an auto variable:
17:init.c **** y =3D x[z];
218 .LM7:
219 0031 8B45C0 movl -64(%ebp), %eax
220 0034 89C0 movl %eax, %eax
221 0036 8D148500 leal 0(,%eax,4), %edx
221 000000
222 003d 8D45C8 leal -56(%ebp), %eax
223 0040 89C0 movl %eax, %eax
224 0042 8B0402 movl (%edx,%eax), %eax
225 0045 8945C4 movl %eax, -60(%ebp)
18:init.c **** y =3D *(x + z);
227 .LM8:
228 0048 8B45C0 movl -64(%ebp), %eax
229 004b 8B4485C8 movl -56(%ebp,%eax,4), %eax
230 004f 8945C4 movl %eax, -60(%ebp)
Hmp. Subscripting with a variable results in more instructions
compared to the manual dereference, at least under these
circumnstances (gcc compiler, debugging turned on, no optimization).
This is one specific case, using one specific compiler with one
specific set of compiler settings. If I turn on optimization, those
differences may disappear. Or they may not. It may turn out to be
that using subscript notation *really is* less efficient (or at least
requires more instructions) than manually adding offsets and
dereferencing in most circumstances.
And unless you're failing to meet a *hard* space or performance
requirement AND array accesses are the absolute last place you can
squeeze out those last few bytes and/or cycles *AND* you *know* that
pointer notation will result in fewer/faster instructions, use
subscript notation (x[i]). It's easier to read (especially for
multidimensional array accesses) and it more clearly conveys intent.
When you're thinking about this kind of micro-optimization, you have
to ask yourself the following questions:
1. How many times am I executing this operation? Do I do it once
over the lifetime of the program (in which case any gains are down in
the noise), or do I repeat the operation hundreds or thousands (or
more) times (in which case the gains are measurable)?
2. Have I *measured* the performance difference between the two
versions? Under a variety of conditions?
3. Are these differences consistent across different compilers?
Would leaving the code alone and simply switching to a different/
better compiler buy me the performance I need?
4. What is the tradeoff in terms of readability/maintainability?
Would I rather debug code that reads
x =3D y[i][j++][++k];
or
x =3D *(*(*(y + i) + j++) + ++k);
Both hurt to look at, but IMO the first hurts less. YMMV.
|
|
0
|
|
|
|
Reply
|
jfbode1029 (227)
|
2/9/2012 12:06:43 AM
|
|
John Bode wrote:
> On Feb 7, 3:28�pm, peter wrote:
> > I am currently exploring the world of pointers and have encounter
> > some inconsistent information regarding the best way to reference
> > an array: array[1] � OR � �*(array +1).
> >
> > One book says that you should not use the syntax array[1] because
> > of performance reason.
>
> FWIW, subscript notation *may* result in a few more instructions at
> the assembly level than pointer notation. Here are some examples
> compiled with gcc -g -Wa,aldh:
>
[examples snipped]
>
> Hmp. Subscripting with a variable results in more instructions
> compared to the manual dereference, at least under these
> circumnstances (gcc compiler, debugging turned on, no optimization).
Looking at the code generated with no optimization is pointless--if you
care about performance, you need to turn on optimizations; it's as
simple as that. GCC generates really horrible code with optimizations
off, as exemplified by the *two* "mov eax, eax" instructions in your
sample code.
|
|
0
|
|
|
|
Reply
|
prl1 (101)
|
2/9/2012 7:25:10 AM
|
|
On Feb 7, 9:28=A0pm, peter <pc...@nospam.mail.com.br> wrote:
> I am currently exploring the world of pointers and have encounter some
> inconsistent information regarding the best way to reference an
> array: array[1] =A0 OR =A0 =A0*(array +1).
which is shortest and clearest? I'm much more of a fan of array
notation. Simple, clear and less typing. Modern compilers (anything in
the last 20 years or so) generate identical code anyway.
The only time I tend to use pointers is say picking a comms packet
apart.
pkt_ptr =3D &packet [0];
type =3D *pkt_ptr++;
length =3D (*pkt_ptr) * 256 + *pkt_ptr;
pkt_ptr +=3D 2;
Each time you read a byte you advance the pointer you don't have to
keep track and count bytes yourself. So is the CRC field in byte 21 or
byte 22? Well it depends if the Qualifier option was selected.
> One book says that you should not use the syntax array[1] because
> of performance reason.
bad reason. It likely makes no difference.
1. write clear, correct code
2. test it thoughly
3. if its too slow make it faster
step 3 is not necessary far more often tahn many people imagine.
People often *start* at step 3. "wow that's /really/ fast, all you
have to do now is make it give the right answer!"
> Another book says that the syntax array[1] is
> only used by FORTRAN programmers who do not understand c pointers.
burn the book.
blacklist the place you bought it
tell your friends
hell, tell us! What was this book?
> So
> what is the true oh wizards? Does it make a difference?
WRITE SIMPLE CODE
|
|
0
|
|
|
|
Reply
|
nick_keighley_nospam (4574)
|
2/9/2012 8:20:23 AM
|
|
On Feb 9, 1:25=A0am, Philip Lantz <p...@canterey.us> wrote:
> John Bode wrote:
> > On Feb 7, 3:28=A0pm, peter wrote:
> > > I am currently exploring the world of pointers and have encounter
> > > some inconsistent information regarding the best way to reference
> > > an array: array[1] =A0 OR =A0 =A0*(array +1).
>
> > > One book says that you should not use the syntax array[1] because
> > > of performance reason.
>
> > FWIW, subscript notation *may* result in a few more instructions at
> > the assembly level than pointer notation. =A0Here are some examples
> > compiled with gcc -g -Wa,aldh:
>
> [examples snipped]
>
> > Hmp. =A0Subscripting with a variable results in more instructions
> > compared to the manual dereference, at least under these
> > circumnstances (gcc compiler, debugging turned on, no optimization).
>
> Looking at the code generated with no optimization is pointless--if you
> care about performance, you need to turn on optimizations; it's as
> simple as that. GCC generates really horrible code with optimizations
> off, as exemplified by the *two* "mov eax, eax" instructions in your
> sample code.
Right. I was trying to make two different points and wound up munging
them together.
First, just because "a[i]" is defined as "*(a+i)" doesn't mean that a
given compiler will always generate the same machine code for both
under all conditions (your point is valid, but orthogonal to the
argument I'm trying to make).
Second, *even if* array notation results in less efficient code, use
it in preference of pointer notation *unless* you're failing to meet a
hard performance requirement and you've exhausted all other sources of
optimization (including compiler settings).
|
|
0
|
|
|
|
Reply
|
jfbode1029 (227)
|
2/9/2012 1:34:34 PM
|
|
=E5=9C=A8 2012=E5=B9=B42=E6=9C=889=E6=97=A5=E6=98=9F=E6=9C=9F=E5=9B=9BUTC+8=
=E4=B8=8B=E5=8D=884=E6=97=B620=E5=88=8623=E7=A7=92=EF=BC=8CNick Keighley=E5=
=86=99=E9=81=93=EF=BC=9A
> On Feb 7, 9:28=C2=A0pm, peter=20
> wrote:
>=20
> > I am currently exploring the world of pointers and have encounter some
> > inconsistent information regarding the best way to reference an
> > array: array[1] =C2=A0 OR =C2=A0 =C2=A0*(array +1).
>=20
> which is shortest and clearest? I'm much more of a fan of array
> notation. Simple, clear and less typing. Modern compilers (anything in
> the last 20 years or so) generate identical code anyway.
>=20
> The only time I tend to use pointers is say picking a comms packet
> apart.
>=20
> pkt_ptr =3D &packet [0];
> type =3D *pkt_ptr++;
> length =3D (*pkt_ptr) * 256 + *pkt_ptr;
> pkt_ptr +=3D 2;
>=20
> Each time you read a byte you advance the pointer you don't have to
> keep track and count bytes yourself. So is the CRC field in byte 21 or
> byte 22? Well it depends if the Qualifier option was selected.
>=20
> > One book says that you should not use the syntax array[1] because
> > of performance reason.
>=20
> bad reason. It likely makes no difference.
>=20
> 1. write clear, correct code
> 2. test it thoughly
> 3. if its too slow make it faster
>=20
> step 3 is not necessary far more often tahn many people imagine.
> People often *start* at step 3. "wow that's /really/ fast, all you
> have to do now is make it give the right answer!"
>=20
> > Another book says that the syntax array[1] is
> > only used by FORTRAN programmers who do not understand c pointers.
>=20
> burn the book.
>=20
> blacklist the place you bought it
>
Don't burn the book. That is not the way to learn black magics in manny
books in the sophomore or above levels.=20
=20
=20
> tell your friends
>=20
> hell, tell us! What was this book?
>=20
> > So
> > what is the true oh wizards? Does it make a difference?
>=20
> WRITE SIMPLE CODE
Learn to write more black spells in the graduate school levels.=20
Don't be so innocent like a child in the elementary school.
|
|
0
|
|
|
|
Reply
|
dihedral88888 (786)
|
2/10/2012 7:42:52 AM
|
|
John Bode wrote:
> On Feb 9, 1:25�am, Philip Lantz wrote:
> > Looking at the code generated with no optimization is pointless--
> > if you care about performance, you need to turn on optimizations;
> > it's as simple as that.
>
> Right. I was trying to make two different points and wound up munging
> them together.
>
> First, just because "a[i]" is defined as "*(a+i)" doesn't mean that a
> given compiler will always generate the same machine code for both
> under all conditions (your point is valid, but orthogonal to the
> argument I'm trying to make).
>
> Second, *even if* array notation results in less efficient code, use
> it in preference of pointer notation *unless* you're failing to meet a
> hard performance requirement and you've exhausted all other sources of
> optimization (including compiler settings).
Yup, I totally agree with both of those. Thanks for clarifying.
|
|
0
|
|
|
|
Reply
|
prl1 (101)
|
2/10/2012 9:04:30 AM
|
|
On Feb 9, 8:20=A0am, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
>> So
>> what is the true oh wizards? Does it make a difference?
>
> WRITE SIMPLE CODE
Amen.
"Programs must be written for people to read, and only incidentally
for machines to execute." -- Abelson & Sussman, Structure and
Interpretation of Computer Programs
|
|
0
|
|
|
|
Reply
|
gwowen (518)
|
2/10/2012 9:20:53 AM
|
|
On Thu, 9 Feb 2012 00:20:23 -0800 (PST), Nick Keighley
<nick_keighley_nospam@hotmail.com> wrote:
> On Feb 7, 9:28�pm, peter <pc...@nospam.mail.com.br> wrote:
<snip>
> The only time I tend to use pointers is say picking a comms packet
> apart.
>
> pkt_ptr = &packet [0];
> type = *pkt_ptr++;
> length = (*pkt_ptr) * 256 + *pkt_ptr;
> pkt_ptr += 2;
>
I really hope you meant
length = pkt_ptr[0] * 256 + pkt_ptr[1]; pkt_ptr += 2;
or one of the several equivalent vairants. Or possibly
len = *pkt_ptr++;
len = len * 256 + *pkt_ptr++;
or again variants, but critically with a sequence point somehow.
> Each time you read a byte you advance the pointer you don't have to
> keep track and count bytes yourself. So is the CRC field in byte 21 or
> byte 22? Well it depends if the Qualifier option was selected.
>
That works with an index variable also.
int i = 0; // or unsigned or size_t
type = pkt[i++];
len = pkt[i] * 256 + pkt[i+1]; i += 2;
or other variants similarly.
I've even been known to write
len = pkt[i+0] * 256 + pkt[i+1; i += 2;
to show the symmetry, and count on the compiler optimizing +0.
And FW(L)IW it's theoretically safer to check
if( i + len > size_read ) /* invalid */
than
if( ptr + len > buf + size_read ) /* invalid */
since merely forming an invalid pointer, even without dereferencing
it, is Undefined Behavior, while an out-of-expected-range integer is
not, except for signed overflow which is often easier to avoid.
<snip rest>
|
|
0
|
|
|
|
Reply
|
dave.thompson2 (767)
|
2/19/2012 4:12:25 AM
|
|
On 2012-02-19, David Thompson <dave.thompson2@verizon.net> wrote:
> On Thu, 9 Feb 2012 00:20:23 -0800 (PST), Nick Keighley
><nick_keighley_nospam@hotmail.com> wrote:
>
>> On Feb 7, 9:28 pm, peter <pc...@nospam.mail.com.br> wrote:
><snip>
>> The only time I tend to use pointers is say picking a comms packet
>> apart.
>>
>> pkt_ptr = &packet [0];
>> type = *pkt_ptr++;
>> length = (*pkt_ptr) * 256 + *pkt_ptr;
>> pkt_ptr += 2;
>>
> I really hope you meant
> length = pkt_ptr[0] * 256 + pkt_ptr[1]; pkt_ptr += 2;
> or one of the several equivalent vairants. Or possibly
> len = *pkt_ptr++;
> len = len * 256 + *pkt_ptr++;
> or again variants, but critically with a sequence point somehow.
If we could throw away sequence points and have left-to-right evaluation,
we could simply write:
length = 256 * *pkt_ptr++ + *pkt_ptr++;
Thus:
>> Each time you read a byte you advance the pointer you don't have to
>> keep track and count bytes yourself. So is the CRC field in byte 21 or
>> byte 22? Well it depends if the Qualifier option was selected.
Exactly.
> That works with an index variable also.
> int i = 0; // or unsigned or size_t
> type = pkt[i++];
> len = pkt[i] * 256 + pkt[i+1]; i += 2;
> or other variants similarly.
When I write this kind of code, I have the sense that I'm being the "human
compiler".
In my head I wrote this:
length = 256 * *pkt_ptr++ + *pkt_ptr++;
But the nice, well-ordered language in my well-ordered mind has to be compiled
by hand into the disordered language in the machine, e.g.:
length = 256 * *pkt_ptr++;
length += *pkt_ptr++;
|
|
0
|
|
|
|
Reply
|
kaz15 (1129)
|
2/19/2012 5:53:16 AM
|
|
peter wrote:
) I am currently exploring the world of pointers and have encounter some
) inconsistent information regarding the best way to reference an
) array: array[1] OR *(array +1).
)
) One book says that you should not use the syntax array[1] because
) of performance reason.
That book is completely and utterly wrong.
In C, "array[index]" is *exactly the same* as "*(array + index)"
I would go so far as to call it syntactic sugar.
Hell, it's even commutative. "array[index]" means the same as "index[array]" !
) Another book says that the syntax array[1] is
) only used by FORTRAN programmers who do not understand c pointers.
That sounds like nothing but evangelism.
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
|
|
0
|
|
|
|
Reply
|
willem6 (255)
|
2/19/2012 12:32:16 PM
|
|
On 19.02.2012 06:53, Kaz Kylheku wrote:
> If we could throw away sequence points and have left-to-right evaluation,
> we could simply write:
>
> length = 256 * *pkt_ptr++ + *pkt_ptr++;
>
But we don't, so we can't. I don't get what your difficulties are with
that. C is the way it is, Java is different. In case you didn't notice,
Java is built on different principles: C's directive is "trust the
programmer" (though the inclusion of complex and imaginary numbers
somewhat goes against this) and Java's directive is "protect the
programmer from his own mistakes".
Where Java falls short is that the really bad mistakes programmers make
aren't the kind a compiler could find. But OK, there are nearly-as-bad
mistakes that Java takes care of nicely (memory-leaks, free-after-use,
access violations with corruption, ...). Only sometimes it is too
obsessive with that. Like, it doesn't let you use variables that may be
uninitialized. Which would be a lot more helpful if the compiler
actually made a proper data-flow analysis instead of the half-assed
stuff it's doing currently. Try the following test class:
public class Test {
public static void main(String[] args)
{
int i;
if (args.length > 3)
i = 3;
if (args.length <= 3)
i = 2;
System.out.println(i);
}
}
and compare the output of the compiler with what you get from a decent C
compiler at highest warning level when fed this source code:
#include <stdio.h>
int main(int argc, char* argv[])
{
int i;
(void) argv;
if (argc > 3)
i = 3;
if (argc <= 3)
i = 2;
printf("%d\n", i);
return 0;
}
And I don't get what is so hard about
length = (pkt_ptr[0] << 8) + pkt_ptr[1];
pkt_ptr += 2;
either.
> Thus:
>
>>> Each time you read a byte you advance the pointer you don't have to
>>> keep track and count bytes yourself. So is the CRC field in byte 21 or
>>> byte 22? Well it depends if the Qualifier option was selected.
>
> Exactly.
>
>> That works with an index variable also.
>> int i = 0; // or unsigned or size_t
>> type = pkt[i++];
>> len = pkt[i] * 256 + pkt[i+1]; i += 2;
>> or other variants similarly.
>
> When I write this kind of code, I have the sense that I'm being the "human
> compiler".
>
> In my head I wrote this:
>
> length = 256 * *pkt_ptr++ + *pkt_ptr++;
>
If you want to write a line like this, you can! Just don't feed it a C
compiler, but Java, if that's what you want.
Otherwise, why don't you just build a C compiler with that rule
implemented? The behaviour is undefined by C which means that your
compiler would still be conforming.
> But the nice, well-ordered language in my well-ordered mind has to be compiled
> by hand into the disordered language in the machine, e.g.:
>
> length = 256 * *pkt_ptr++;
> length += *pkt_ptr++;
>
You really don't know what compiling by hand is. If you were ever in a
situation where operator overloading of C++ truly was helpful, then
you'll know if you had to rewrite that stuff into C. (Yeah, I think the line
y = 2 * x + 15 * a + (b - c) / d;
was better than the block
{
Rational t1, t2, t3;
rat_set_i(&t1, 2, 1);
rat_mul(&t1, &t1, &x);
rat_set_i(&t2, 15, 1);
rat_mul(&t2, &t2, &a);
rat_add(&t1, &t1, &t2);
rat_sub(&t3, &b, &c);
rat_div(&t3, &t3, &d);
rat_add(&y, &t1, &t3);
}
)
Ciao,
Markus
|
|
0
|
|
|
|
Reply
|
nullplan (53)
|
2/19/2012 5:54:35 PM
|
|
Markus Wichmann wrote:
) You really don't know what compiling by hand is. If you were ever in a
) situation where operator overloading of C++ truly was helpful, then
) you'll know if you had to rewrite that stuff into C. (Yeah, I think the line
)
) y = 2 * x + 15 * a + (b - c) / d;
)
) was better than the block
)
) {
) Rational t1, t2, t3;
) rat_set_i(&t1, 2, 1);
) rat_mul(&t1, &t1, &x);
) rat_set_i(&t2, 15, 1);
) rat_mul(&t2, &t2, &a);
) rat_add(&t1, &t1, &t2);
) rat_sub(&t3, &b, &c);
) rat_div(&t3, &t3, &d);
) rat_add(&y, &t1, &t3);
) }
That's a bit unfair (just a bit though):
y = rat_add(rat_mul(rat_int(2), x),
rat_add(rat_mul(rat_int(15), a),
rat_div(rat_sub(b, c), d)));
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
|
|
0
|
|
|
|
Reply
|
willem6 (255)
|
2/19/2012 6:51:19 PM
|
|
Markus Wichmann <nullplan@gmx.net> writes:
>if (args.length > 3)
> i = 3;
>if (args.length <= 3)
> i = 2;
But in this special case, an if-then-else would be nicer.
And then you can even declare �i� as constant in Java:
{ final int i; if( args.length > 3 )i = 3; else i = 2; ... }
Though I'd always prefer
final int i =( args.length > 3 )3 : 2;
.
|
|
0
|
|
|
|
Reply
|
ram (2827)
|
2/19/2012 6:54:09 PM
|
|
Willem <willem@toad.stack.nl> writes:
> peter wrote:
> ) I am currently exploring the world of pointers and have encounter some
> ) inconsistent information regarding the best way to reference an
> ) array: array[1] OR *(array +1).
> )
> ) One book says that you should not use the syntax array[1] because
> ) of performance reason.
>
> That book is completely and utterly wrong.
> In C, "array[index]" is *exactly the same* as "*(array + index)"
> I would go so far as to call it syntactic sugar.
> Hell, it's even commutative. "array[index]" means the same as "index[array]" !
[...]
Yes, but I doubt that that's what the book actually said. I'm only
guessing, but the book was probably advocating code like this:
void func(char *s) {
while (*s != '\0') {
do_something_with(*s);
s++;
}
}
over this:
void func(char *s) {
size_t i = 0;
while (s[i] != '\0') {
do_something_with(s[i]);
i++;
}
}
The former, by updating the pointer on each iteration, avoids
redoing the index calculation, which might be moderately expenstive,
especially for arrays of something bigger than char.
It's a largely obsolete argument, since modern optimizing compilers can
generate the same code for both, but it's not "completely and utterly
wrong".
I'd be interested in knowing which book the previous poster was
referring to, how old it is, and what it actually says.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
kst-u (21469)
|
2/19/2012 8:21:15 PM
|
|
"Markus Wichmann" <nullplan@gmx.net> ha scritto nel messaggio
news:rjp719-cl5.ln1@voyager.wichi.de.vu...
> y = 2 * x + 15 * a + (b - c) / d;
> was better than the block
>
> {
> Rational t1, t2, t3;
> rat_set_i(&t1, 2, 1);
> rat_mul(&t1, &t1, &x);
> rat_set_i(&t2, 15, 1);
> rat_mul(&t2, &t2, &a);
> rat_add(&t1, &t1, &t2);
> rat_sub(&t3, &b, &c);
> rat_div(&t3, &t3, &d);
> rat_add(&y, &t1, &t3);
> }
>
> )
the right way for that above
computation can not be far different from this:
multAssign(&y, 2, x)|jc .e
multAssign(&t, 15, a)|jc .e
sumAssign(&r, y, t)|jc .e
difAssign(&y, b, c)|jc .e
divAssign(&t, y, d)|jc .e
sumAssign(&y, r, t)|jc .e
[the code above is a pseudo C++ where for example
multAssign() is "i32 multAssign(num* a, i32 i, num& b)"
and jc .e means if there is one error go to .e]
or pheraps
multAssign(y, 2, x)|jc .e
multAssign(t, 15, a)|jc .e
sumAssign(r, y, t)|jc .e
difAssign(y, b, c)|jc .e
divAssign(t, y, d)|jc .e
sumAssign(y, r, t)|jc .e
where all arg of function are pointers so 15 is a pointer in mem
of one number that contain 15
or pheraps
if( Assign(y, 2*x+15*a+(b-c)/d)!=0 ) goto error;
return 0;
error:
return -1;
or pheraps
if( (y:=2*x+15*a+(b-c)/d))!=0 ) goto error;
return 0;
error:
return -1;
so operator := return different of zero if error in assignament
or in the computation of assignament
zero if the assignament is the right result...
> Ciao,
> Markus
ciao
|
|
0
|
|
|
|
Reply
|
io_x
|
2/19/2012 8:29:38 PM
|
|
Keith Thompson wrote:
) Willem <willem@toad.stack.nl> writes:
)> peter wrote:
)> ) I am currently exploring the world of pointers and have encounter some
)> ) inconsistent information regarding the best way to reference an
)> ) array: array[1] OR *(array +1).
)> )
)> ) One book says that you should not use the syntax array[1] because
)> ) of performance reason.
)>
)> That book is completely and utterly wrong.
)> In C, "array[index]" is *exactly the same* as "*(array + index)"
)> I would go so far as to call it syntactic sugar.
)> Hell, it's even commutative. "array[index]" means the same as "index[array]" !
) [...]
)
) Yes, but I doubt that that's what the book actually said.
Granted.
) I'm only
) guessing, but the book was probably advocating code like this:
)
) void func(char *s) {
) while (*s != '\0') {
) do_something_with(*s);
) s++;
) }
) }
)
) over this:
)
) void func(char *s) {
) size_t i = 0;
) while (s[i] != '\0') {
) do_something_with(s[i]);
) i++;
) }
) }
)
) The former, by updating the pointer on each iteration, avoids
) redoing the index calculation, which might be moderately expenstive,
) especially for arrays of something bigger than char.
Or which might not be expensive at all, especially given special indexing
instructions such as those on the x86. Also for types bigger than char.
A long time ago, I did some speed tests on an x86 machine, and it turned
out that there was no speed difference whatsoever between an indexed loop
and a pointer loop.
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
|
|
0
|
|
|
|
Reply
|
willem6 (255)
|
2/19/2012 9:00:21 PM
|
|
Willem <willem@toad.stack.nl> writes:
> Keith Thompson wrote:
<snip>
> ) I'm only
> ) guessing, but the book was probably advocating code like this:
> )
> ) void func(char *s) {
> ) while (*s != '\0') {
> ) do_something_with(*s);
> ) s++;
> ) }
> ) }
> )
> ) over this:
> )
> ) void func(char *s) {
> ) size_t i = 0;
> ) while (s[i] != '\0') {
> ) do_something_with(s[i]);
> ) i++;
> ) }
> ) }
> )
> ) The former, by updating the pointer on each iteration, avoids
> ) redoing the index calculation, which might be moderately expenstive,
> ) especially for arrays of something bigger than char.
>
> Or which might not be expensive at all, especially given special indexing
> instructions such as those on the x86. Also for types bigger than char.
>
> A long time ago, I did some speed tests on an x86 machine, and it turned
> out that there was no speed difference whatsoever between an indexed loop
> and a pointer loop.
With a relatively recent gcc, there's no need to test, at least for this
code. You get the same instructions for the loop body (with -O2) for
both loops.
--
Ben.
|
|
0
|
|
|
|
Reply
|
ben.usenet (6515)
|
2/19/2012 9:42:12 PM
|
|
On 19.02.2012 19:54, Stefan Ram wrote:
> Markus Wichmann <nullplan@gmx.net> writes:
>> if (args.length > 3)
>> i = 3;
>> if (args.length <= 3)
>> i = 2;
>
> But in this special case, an if-then-else would be nicer.
> And then you can even declare »i« as constant in Java:
>
> { final int i; if( args.length > 3 )i = 3; else i = 2; ... }
>
> Though I'd always prefer
>
> final int i =( args.length > 3 )3 : 2;
>
> .
>
The example was chosen deliberately to show the flaws in the Java
data-flow analyzer: With if-else the code compiles, without it, the
compiler aborts on account of "i may not be initialized".
gcc does not generate a "may not be initialized" warning in the C code I
wrote below that (yes, I know that I have to activate the optimizer to
see those). Which means it is entirely possible for a program to see
that there is no code path to a read on i without prior initialization.
And by now we got totally off-topic...
Ciao,
Markus
|
|
0
|
|
|
|
Reply
|
nullplan (53)
|
2/20/2012 10:24:29 AM
|
|
Keith Thompson wrote:
>
> Willem <willem@toad.stack.nl> writes:
> > peter wrote:
> > ) I am currently exploring the world of pointers and have encounter some
> > ) inconsistent information regarding the best way to reference an
> > ) array: array[1] OR *(array +1).
> > )
> > ) One book says that you should not use the syntax array[1] because
> > ) of performance reason.
> >
> > That book is completely and utterly wrong.
> > In C, "array[index]" is *exactly the same* as "*(array + index)"
> > I would go so far as to call it syntactic sugar.
> > Hell, it's even commutative. "array[index]" means the same as "index[array]" !
> [...]
>
> Yes, but I doubt that that's what the book actually said.
Teach Yourself C,
by Herbert Schildt, copyright 1990,
Chapter 6.3, Use Pointers With Arrays,
page 197:
For somewhat complex reasons,
a C compiler will generally create faster executable code
for an expression such as
*(p+3)
than it will for the comparable array index
p[3]
--
pete
|
|
0
|
|
|
|
Reply
|
pfiland (6613)
|
2/20/2012 10:32:27 PM
|
|
On 02/20/2012 05:32 PM, pete wrote:
....
> Teach Yourself C,
> by Herbert Schildt, copyright 1990,
> Chapter 6.3, Use Pointers With Arrays,
> page 197:
>
> For somewhat complex reasons,
> a C compiler will generally create faster executable code
> for an expression such as
>
> *(p+3)
>
> than it will for the comparable array index
>
> p[3]
Schildt is a notoriously unreliable source of information about C. It's
possible that what he said was true for some of the compilers he was
most familiar with at the time he wrote that - but I wouldn't recommend
assuming that this was the case. It's certainly not generally true, and
it's far less likely to be the case for modern compiler than it was for
those available in 1990.
--
James Kuyper
|
|
0
|
|
|
|
Reply
|
jameskuyper (5157)
|
2/20/2012 10:56:39 PM
|
|
pete <pfiland@mindspring.com> writes:
> Keith Thompson wrote:
>> Willem <willem@toad.stack.nl> writes:
>> > peter wrote:
>> > ) I am currently exploring the world of pointers and have encounter some
>> > ) inconsistent information regarding the best way to reference an
>> > ) array: array[1] OR *(array +1).
>> > )
>> > ) One book says that you should not use the syntax array[1] because
>> > ) of performance reason.
>> >
>> > That book is completely and utterly wrong.
>> > In C, "array[index]" is *exactly the same* as "*(array + index)"
>> > I would go so far as to call it syntactic sugar.
>> > Hell, it's even commutative. "array[index]" means the same as "index[array]" !
>> [...]
>>
>> Yes, but I doubt that that's what the book actually said.
>
> Teach Yourself C,
> by Herbert Schildt, copyright 1990,
> Chapter 6.3, Use Pointers With Arrays,
> page 197:
>
> For somewhat complex reasons,
> a C compiler will generally create faster executable code
> for an expression such as
>
> *(p+3)
>
> than it will for the comparable array index
>
> p[3]
Had I known it was one of Schildt's books, I wouldn't have assumed
that it said something sensible. (Do we know that that's the book to
which peter was referring?)
Willem is right: the book is completely and utterly wrong.
There's probably a valid point somewhere in the vicinity of what
Schildt wrote (as I discussed upthread), but Schildt missed it.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
kst-u (21469)
|
2/20/2012 11:19:48 PM
|
|
Keith Thompson <kst-u@mib.org> writes:
> pete <pfiland@mindspring.com> writes:
>> Keith Thompson wrote:
>>> Willem <willem@toad.stack.nl> writes:
>>> > peter wrote:
>>> > ) I am currently exploring the world of pointers and have encounter some
>>> > ) inconsistent information regarding the best way to reference an
>>> > ) array: array[1] OR *(array +1).
>>> > )
>>> > ) One book says that you should not use the syntax array[1] because
>>> > ) of performance reason.
>>> >
>>> > That book is completely and utterly wrong.
>>> > In C, "array[index]" is *exactly the same* as "*(array + index)"
>>> > I would go so far as to call it syntactic sugar.
>>> > Hell, it's even commutative. "array[index]" means the same as "index[array]" !
>>> [...]
>>>
>>> Yes, but I doubt that that's what the book actually said.
>>
>> Teach Yourself C,
>> by Herbert Schildt, copyright 1990,
>> Chapter 6.3, Use Pointers With Arrays,
>> page 197:
>>
>> For somewhat complex reasons,
>> a C compiler will generally create faster executable code
>> for an expression such as
>>
>> *(p+3)
>>
>> than it will for the comparable array index
>>
>> p[3]
>
> Had I known it was one of Schildt's books, I wouldn't have assumed
> that it said something sensible. (Do we know that that's the book to
> which peter was referring?)
>
> Willem is right: the book is completely and utterly wrong.
> There's probably a valid point somewhere in the vicinity of what
> Schildt wrote (as I discussed upthread), but Schildt missed it.
Let me amend that slightly. It's possible that some compilers might
generate faster code for *(p+3) than for p[3]. There's no good reason
for that, since the two expressions are equivalent by definition, but
it's possible. It's also possible Schildt encountered such a compiler
and reached an overly general conclusion.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
kst-u (21469)
|
2/21/2012 12:35:57 AM
|
|
Keith Thompson wrote:
>
> Keith Thompson <kst-u@mib.org> writes:
> > pete <pfiland@mindspring.com> writes:
> >> Keith Thompson wrote:
> >>> Willem <willem@toad.stack.nl> writes:
> >>> > peter wrote:
> >>> > ) I am currently exploring the world of pointers and have encounter some
> >>> > ) inconsistent information regarding the best way to reference an
> >>> > ) array: array[1] OR *(array +1).
> >>> > )
> >>> > ) One book says that you should not use the syntax array[1] because
> >>> > ) of performance reason.
> >>> >
> >>> > That book is completely and utterly wrong.
> >>> > In C, "array[index]" is *exactly the same* as "*(array + index)"
> >>> > I would go so far as to call it syntactic sugar.
> >>> > Hell, it's even commutative. "array[index]" means the same as "index[array]" !
> >>> [...]
> >>>
> >>> Yes, but I doubt that that's what the book actually said.
> >>
> >> Teach Yourself C,
> >> by Herbert Schildt, copyright 1990,
> >> Chapter 6.3, Use Pointers With Arrays,
> >> page 197:
> >>
> >> For somewhat complex reasons,
> >> a C compiler will generally create faster executable code
> >> for an expression such as
> >>
> >> *(p+3)
> >>
> >> than it will for the comparable array index
> >>
> >> p[3]
> >
> > Had I known it was one of Schildt's books, I wouldn't have assumed
> > that it said something sensible. (Do we know that that's the book to
> > which peter was referring?)
I don't know,
but for some reason I remembered reading it a long time ago.
> > Willem is right: the book is completely and utterly wrong.
> > There's probably a valid point somewhere in the vicinity of what
> > Schildt wrote (as I discussed upthread), but Schildt missed it.
>
> Let me amend that slightly. It's possible that some compilers might
> generate faster code for *(p+3) than for p[3]. There's no good reason
> for that, since the two expressions are equivalent by definition, but
> it's possible. It's also possible Schildt encountered such a compiler
> and reached an overly general conclusion.
I recall a thread about a year or so ago,
where the controling expression in a loop
was shown to have been rendered
with a register, when {!= 0} was omitted.
That is to say that there was a compiler for which
while (x)
was faster than
while ((x) != 0)
I think it was a gcc compiler
and I remember being disappointed
that the compiler had translated
two semantically equal expressions differently.
--
pete
|
|
0
|
|
|
|
Reply
|
pfiland (6613)
|
2/21/2012 3:53:13 AM
|
|
pete <pfiland@mindspring.com> writes:
[...]
> I recall a thread about a year or so ago,
> where the controling expression in a loop
> was shown to have been rendered
> with a register, when {!= 0} was omitted.
> That is to say that there was a compiler for which
> while (x)
> was faster than
> while ((x) != 0)
> I think it was a gcc compiler
> and I remember being disappointed
> that the compiler had translated
> two semantically equal expressions differently.
That would be relevant only if it behaved that way with optimization
enabled.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
|
|
0
|
|
|
|
Reply
|
kst-u (21469)
|
2/21/2012 5:16:34 AM
|
|
On Mon, 20 Feb 2012 16:35:57 -0800, Keith Thompson <kst-u@mib.org>
wrote:
>Let me amend that slightly. It's possible that some compilers might
>generate faster code for *(p+3) than for p[3]. There's no good reason
>for that, since the two expressions are equivalent by definition, but
>it's possible. It's also possible Schildt encountered such a compiler
>and reached an overly general conclusion.
I had that book at one time. The book was explicitly for Borland C++.
|
|
0
|
|
|
|
Reply
|
lnr729 (8)
|
2/21/2012 8:26:00 AM
|
|
On Feb 19, 5:54=A0pm, Markus Wichmann <nullp...@gmx.net> wrote:
> On 19.02.2012 06:53, Kaz Kylheku wrote:
> > =A0 length =3D 256 * *pkt_ptr++ + *pkt_ptr++;
> And I don't get what is so hard about
> length =3D (pkt_ptr[0] << 8) + pkt_ptr[1];
> pkt_ptr +=3D 2;
One piece of code is intended to demonstrate how smart the programmer
is.
One piece of code intended to be understood, debugged and maintained
by humans, though personally I'd prefer (pkt_ptr[0] * 256).
|
|
0
|
|
|
|
Reply
|
gwowen (518)
|
2/21/2012 9:51:17 AM
|
|
Richard Sanders wrote:
>
> On Mon, 20 Feb 2012 16:35:57 -0800, Keith Thompson <kst-u@mib.org>
> wrote:
>
> >Let me amend that slightly. It's possible that some compilers might
> >generate faster code for *(p+3) than for p[3].
> >There's no good reason
> >for that, since the two expressions are equivalent by definition, but
> >it's possible.
> >It's also possible Schildt encountered such a compiler
> >and reached an overly general conclusion.
>
> I had that book at one time. The book was explicitly for Borland C++.
Not very explicitly:
Introduction xvii
About This Book
This book teaches ANSI standard C.
This ensures that your knowledge will be applicable
to the widest range of C environments.
--
pete
|
|
0
|
|
|
|
Reply
|
pfiland (6613)
|
2/21/2012 4:46:09 PM
|
|
|
45 Replies
18 Views
(page loaded in 0.328 seconds)
|