| ??? 05/04/08 00:37 Modified: 05/04/08 02:25 Read: times Msg Score: +2 +1 Good Answer/Helpful +1 Informative |
#154357 - No Responding to: ???'s previous message |
Erik said:
if (buffer[index + 8] == 0x47)
index+8 figured at run time if ((buffer + 8)[index] == 0x47) buffer+8 figured at compile time This might be true for some compilers, but it's certainly not true for all of them, and a person would be ill-advised to base his coding style on such a superstitious notion. Here's a quote from K&R (except that I changed 'i' to 'j' so the subscripts don't get mistaken for italics tags. Craig. ;-) ): Kernighan and Ritchie said:
... a reference to a[j] can also be written as *(a+j). In evaluating a[j], C converts it to *(a+j) immediately; the two forms are completely equivalent. If we apply that rule to Erik's examples, we see that buffer[index+8] is equivalent to *(buffer+index+8), and (buffer+8)[index] is equivalent to *(buffer+8+index). So it's clear that a sufficiently smart compiler could, should, and would calculate buffer+8 at compile time in either case, regardless of whether the target processor was a '51 or a Pentium or a single-tape Turing machine. As an example, here's some output from Microsoft's hotdog C/C++ compiler for the 80x86:
if (buffer[index + 8] == 0x47) break;
004113A1 0F B6 05 78 71 41 00 movzx eax,byte ptr [index (417178h)]
004113A8 0F B6 88 84 71 41 00 movzx ecx,byte ptr buffer+8 (417184h)[eax]
004113AF 83 F9 47 cmp ecx,47h
004113B2 75 02 jne wmain+56h (4113B6h)
004113B4 EB 2C jmp wmain+82h (4113E2h)
if ((buffer + 8)[index] == 0x47) break;
004113B6 0F B6 05 78 71 41 00 movzx eax,byte ptr [index (417178h)]
004113BD 0F B6 88 84 71 41 00 movzx ecx,byte ptr buffer+8 (417184h)[eax]
004113C4 83 F9 47 cmp ecx,47h
004113C7 75 02 jne wmain+6Bh (4113CBh)
004113C9 EB 17 jmp wmain+82h (4113E2h)
if (buffer[index] == 0x47) break;
004113CB 0F B6 05 78 71 41 00 movzx eax,byte ptr [index (417178h)]
004113D2 0F B6 88 7C 71 41 00 movzx ecx,byte ptr buffer (41717Ch)[eax]
004113D9 83 F9 47 cmp ecx,47h
004113DC 75 02 jne wmain+80h (4113E0h)
004113DE EB 02 jmp wmain+82h (4113E2h)
Note that it generates essentially the same code for both of Erik's examples, as well as a third example where the "+ 8" is missing entirely.
Closer to home, the Keil compiler also gets it right, showing that there is no distinction to be made in this context between a "Real C" compiler (whatever that means) and one for "'51 C" (whatever that means).
C51 COMPILER V7.05, COMPILATION OF MODULE TEST
OBJECT MODULE PLACED IN test.OBJ
COMPILER INVOKED BY: C:\SiLabs\MCU\IDEfiles\C51\BIN\C51.exe test.c DB OE CD SB
stmt level source
1 unsigned char buffer[10];
2 unsigned char index;
3
4 void main() {
5 1 for (index=0; index<=254; index++) {
6 2 if (buffer[index + 8] == 0x47) break;
7 2 if ((buffer + 8)[index] == 0x47) break;
8 2 if (buffer[index] == 0x47) break;
9 2 }
10 1 }
11
ASSEMBLY LISTING OF GENERATED OBJECT CODE
; FUNCTION main (BEGIN)
; SOURCE LINE # 4
; SOURCE LINE # 5
0000 E4 CLR A
0001 F500 R MOV index,A
0003 ?C0001:
; SOURCE LINE # 6
0003 7400 R MOV A,#LOW buffer+08H
0005 2500 R ADD A,index
0007 F8 MOV R0,A
0008 E6 MOV A,@R0
0009 FF MOV R7,A
000A 6447 XRL A,#047H
000C 6018 JZ ?C0007
000E ?C0004:
; SOURCE LINE # 7
000E EF MOV A,R7
000F 6447 XRL A,#047H
0011 6013 JZ ?C0007
0013 ?C0005:
; SOURCE LINE # 8
0013 7400 R MOV A,#LOW buffer
0015 2500 R ADD A,index
0017 F8 MOV R0,A
0018 E6 MOV A,@R0
0019 6447 XRL A,#047H
001B 6009 JZ ?C0007
; SOURCE LINE # 9
001D ?C0003:
001D 0500 R INC index
001F E500 R MOV A,index
0021 D3 SETB C
0022 94FE SUBB A,#0FEH
0024 40DD JC ?C0001
; SOURCE LINE # 10
0026 ?C0007:
0026 22 RET
-- Russ
|
| Topic | Author | Date |
| "Real C" vs '51 C | 01/01/70 00:00 | |
| there is nothing wrong except... | 01/01/70 00:00 | |
| if you are not , why are you even here | 01/01/70 00:00 | |
| *(buffer+8+index)? | 01/01/70 00:00 | |
| none of the above | 01/01/70 00:00 | |
| OK then how? | 01/01/70 00:00 | |
| like this | 01/01/70 00:00 | |
| but it's basically the same... | 01/01/70 00:00 | |
| YCMV | 01/01/70 00:00 | |
| No | 01/01/70 00:00 | |
| assumptions | 01/01/70 00:00 | |
| Re: assumptions | 01/01/70 00:00 | |
| I took a \'known\' example | 01/01/70 00:00 | |
| Compiler-independent efficient C | 01/01/70 00:00 | |
| a clarification and an example | 01/01/70 00:00 | |
| Two kinds of "efficiency" | 01/01/70 00:00 | |
| Compiler smarter than coder | 01/01/70 00:00 | |
| Getting the least out of your compiler | 01/01/70 00:00 | |
| Real C is inherently reentrant | 01/01/70 00:00 | |
which, even when possible, often is ill advised | 01/01/70 00:00 |



