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