|
View:
New views
20 Messages
—
Rating Filter:
Alert me
|
| < Prev | 1 - 2 - 3 | Next > |
|
|
Re: using BREAK in 'C'sergio masci wrote:
> switch (x) > { > case 1: > > if (x == a) > { > x++; > } > else > { > case 2: > x = 0; > } > } > > ... > > I've just tried to compile the above using GCC and it went through OK. Yucc! Yet another entry to add to the long list of bad design choices for C. Responsible languages make each case a block so you can't do this. They also optimize for the common case of where you want to execute a single case from the list of choices. If after executing the code for one case you want to execute the next listed case, you should be forced to specify this explicitly. Wirth and Jenson got this right in Pascal, for example, so there was no excuse for K+R to have messed it up later in C. In Pascal a example of the equivalent to a C SWITCH looks like this: case number of {which number did he enter ?} 1: writeln ('Single.'); 2: writeln ('Couple.'); 4: writeln ('Quad.'); 12: writeln ('Dozen.'); 13: begin writeln ('That is a unlucky number.'); writeln ('Beware of heavy trucks when crossing the street.'); goto roll_truck; end; {end of number=13 case} otherwise writeln ('That is not a special number, try again.'); goto retry; end; {end of whole CASE statement} Note that the whole CASE statement is exited after the chosen case is executed. For example, if NUMBER is two the program will print "Couple." and not then continue by printing "Quad.". If you want that, you have to explicitly use a lable and a GOTO. This optimizes for the vast majority of cases where you want to execute the code for a single case only. It makes simple human mistakes less likely to occur in the first place, and more likely to be caught by the compiler when they do occur. ******************************************************************** Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products (978) 742-9014. Gold level PIC consultants since 2000. -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
Re: using BREAK in 'C'> case n: is just a label, that is why it has the colon after it (just like
> any other label in C). That is also why the break leaps out of the switch > statement, just like it jumps out of a while or for statement. > 'case n:' is *not* a label. It *cannot* be the target of a goto. -- Bob Ammerman RAm Systems -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
Re: using BREAK in 'C'>
> Yet another entry to add to the long list of bad design choices for C. > Responsible languages make each case a block so you can't do this. They > also optimize for the common case of where you want to execute a single > case > from the list of choices. If after executing the code for one case you > want > to execute the next listed case, you should be forced to specify this > explicitly. > > Wirth and Jenson got this right in Pascal, for example, so there was no > excuse for K+R to have messed it up later in C. In Pascal a example of the > equivalent to a C SWITCH looks like this: You must realize that they probably knew what they were doing in implementing it the way they did. The above-linked Duff's Device is an example of why the switch statement in C is useful the way it is. Yes, it's a trap sometimes, and yes I've fallen into it, but I think it's worth having it to make the language a worthwhile replacement for hand-coding in assembler, which is what one might have to resort to in order to achieve such a performance boost. -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
Re: using BREAK in 'C'On Mon, 29 Jun 2009, Tamas Rudnai wrote: > On Mon, Jun 29, 2009 at 3:41 PM, sergio masci <smplx@...> wrote: > > > I remember reading some code like this many years ago (can't remember the > > exact details though). It was much more complex than the above and very > > difficult to follow. > > > Do you mean the Duff's device which is combining switch..case to a > do..while? > http://en.wikipedia.org/wiki/Duff%27s_device No not Duff's device. The code I saw definatley had several if statments with case labels scattered through the "then" and "else" statements. It really was very hard to follow. Regards Sergio Masci -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
Re: using BREAK in 'C'Marcel Birthelmer wrote:
> You must realize that they probably knew what they were doing in > implementing it the way they did. No, I think they were a couple of hackers that had no programming discipline and had disdain for languages that tried to enforce it. I think we all know a few people like that, or maybe even were like that back when we first learned to write computer programs. Most of us grow out of it. K+R didn't. > The above-linked Duff's Device is an > example of why the switch statement in C is useful the way it is. > Yes, it's a trap sometimes, and yes I've fallen into it, but I think > it's worth having it to make the language a worthwhile replacement > for hand-coding in assembler, which is what one might have to resort > to in order to achieve such a performance boost. There was no link above, and I didn't pay much attention to the first message about Duff's device. Perhaps if you describe it breifly or provide a example, I can see what the equivalent Pascal would look like and whether a reasonable compiler would produce the same code as C would or not. ******************************************************************** Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products (978) 742-9014. Gold level PIC consultants since 2000. -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
Re: using BREAK in 'C'Here's the example from Wikipedia (slightly modified for (my) readabilitiy):
send(to, from, count) { register n=(count+7)/8; switch(count%8){ case 0: do{ *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; }while(--n>0); } } Basically, 'count' bytes are supposed to be copied to a memory-mapped register (in this case). To dynamically unroll the loop, the first count%8 bytes are written by jumping into the middle of a do/while loop that, afterwards, writes 8 bytes at a time. In assembler, you would probably just do a calculated jump into the middle of that loop. One comment from the wikipedia page (http://en.wikipedia.org/wiki/Duff%27s_device) : C's default fall-through in case statements has long been its most controversial single feature; Duff observed that "This code forms some sort of argument in that debate, but I'm not sure whether it's for or against."[1] - Marcel On Mon, Jun 29, 2009 at 6:28 AM, Olin Lathrop <olin_piclist@...> wrote: > > Marcel Birthelmer wrote: > > You must realize that they probably knew what they were doing in > > implementing it the way they did. > > No, I think they were a couple of hackers that had no programming discipline > and had disdain for languages that tried to enforce it. I think we all know > a few people like that, or maybe even were like that back when we first > learned to write computer programs. Most of us grow out of it. K+R didn't. > > > The above-linked Duff's Device is an > > example of why the switch statement in C is useful the way it is. > > Yes, it's a trap sometimes, and yes I've fallen into it, but I think > > it's worth having it to make the language a worthwhile replacement > > for hand-coding in assembler, which is what one might have to resort > > to in order to achieve such a performance boost. > > There was no link above, and I didn't pay much attention to the first > message about Duff's device. Perhaps if you describe it breifly or provide > a example, I can see what the equivalent Pascal would look like and whether > a reasonable compiler would produce the same code as C would or not. > > > ******************************************************************** > Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products > (978) 742-9014. Gold level PIC consultants since 2000. > -- > http://www.piclist.com PIC/SX FAQ & list archive > View/change your membership options at > http://mailman.mit.edu/mailman/listinfo/piclist -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
Re: using BREAK in 'C'Times were very different when K&R were constructing a programming
language and operating system from scratch. If one doesn't like C, then don't use it. David On 2009-06-29, at 6:28 AM, olin_piclist@... (Olin Lathrop) wrote: > Marcel Birthelmer wrote: >> You must realize that they probably knew what they were doing in >> implementing it the way they did. > > No, I think they were a couple of hackers that had no programming > discipline > and had disdain for languages that tried to enforce it. I think we > all know > a few people like that, or maybe even were like that back when we > first > learned to write computer programs. Most of us grow out of it. K+R > didn't. > >> The above-linked Duff's Device is an >> example of why the switch statement in C is useful the way it is. >> Yes, it's a trap sometimes, and yes I've fallen into it, but I think >> it's worth having it to make the language a worthwhile replacement >> for hand-coding in assembler, which is what one might have to resort >> to in order to achieve such a performance boost. > > There was no link above, and I didn't pay much attention to the first > message about Duff's device. Perhaps if you describe it breifly or > provide > a example, I can see what the equivalent Pascal would look like and > whether > a reasonable compiler would produce the same code as C would or not. > > > ******************************************************************** > Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products > (978) 742-9014. Gold level PIC consultants since 2000. > -- > http://www.piclist.com PIC/SX FAQ & list archive > View/change your membership options at > http://mailman.mit.edu/mailman/listinfo/piclist http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
Re: using BREAK in 'C'On Mon, Jun 29, 2009 at 2:28 PM, Olin Lathrop <olin_piclist@...>wrote:
> There was no link above, and I didn't pay much attention to the first > message about Duff's device. Perhaps if you describe it breifly or provide > a example, I can see what the equivalent Pascal would look like and whether > a reasonable compiler would produce the same code as C would or not. The main purpose of Duff's device is to linearising repetitive tasks which are normally solved by simple loops. This way you can speed up certain tasks like copying of variable length strings -- as you do not need to do a GOTO for every single character. I think it is better described here: http://www.lysator.liu.se/c/duffs-device.html I believe you can do it in other ways, it's just an interesting exploitation of the C language in my opinion. Tamas -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
Re: using BREAK in 'C'>'case n:' is *not* a label. It *cannot* be the target of a goto.
Well, that is exactly what Gerhards code does earlier in this thread. He later explicitly states it is a defined action in C99 ... -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
Re: using BREAK in 'C'On Mon, Jun 29, 2009 at 3:00 PM, David Harris <dpharris@...> wrote:
> Times were very different when K&R were constructing a programming > language and operating system from scratch. If one doesn't like C, > then don't use it. I think many people does not like C (well, those who knows Pascal). But nowadays you "have to" use C as you have everything in C, like Microchip's libraries, but here we can talk about Bytecraft, HiTech, CCS or FED. The route is quite long and steep till you reach the point what Olin has now -- his own libraries and macros and compiler infractructure. Most comanies choose the "easier way" using an existing package which is mostly in C, so you "have to" use C. Tamas -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
|
|
|
|
|
|
Re: using BREAK in 'C'> Hmm. This seems rather dangerous to me. It's definitely making some
> assumptions about how the particular compiler implements things. It's also > not clear this is really a win in machine code. While the C source code > looks compact and possibly efficient at first glance, it could expand into > more than hoped. That's a fair point; moreover, with CPU features commonly available today, it's really not that useful. From the Linux Kernel mailing list ( http://lkml.indiana.edu/hypermail/linux/kernel/0008.2/0171.html ): It turns out that with branch predictions and the relative speed of CPU vs. memory changing over the past decade, loop unrolling is pretty much pointless. In fact, by eliminating all instances of Duff's Device from the XFree86 4.0 server, the server shrunk in size by _half_ _a_ _megabyte_ (!!!), and was faster to boot, because the elimination of all that excess code meant that the X server wasn't thrashing the cache lines as much. -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
Re: using BREAK in 'C'I am not sure if it is mandatory or not but in all C compiler I have seen
the switch-case was compiled either to series of if..goto or optimised in the similar manner, like jump tables or checking range and a goto if there was more than one case in series describing an entire range of literals. If you just do a do { *to++ = *from++; } while(...) or as in more common form while(...) { *to++ = *from++; } then at every character you should execute a GOTO instruction + do the condition in the while statement. With this Duff's device what you do is to bulk copy the characters -- in that example 8 chars a time. And as you cannot grantee that your string has a round number length you need to do that extra effort to copy the remainders of chars. You can save a lot of cycles if your string is long. Tamas On Mon, Jun 29, 2009 at 3:37 PM, Olin Lathrop <olin_piclist@...>wrote: > Marcel Birthelmer wrote: > > Here's the example from Wikipedia (slightly modified for (my) > > readabilitiy): > > > > register n=(count+7)/8; > > switch(count%8){ > > case 0: do{ *to = *from++; > > case 7: *to = *from++; > > case 6: *to = *from++; > > case 5: *to = *from++; > > case 4: *to = *from++; > > case 3: *to = *from++; > > case 2: *to = *from++; > > case 1: *to = *from++; > > }while(--n>0); > > } > > Hmm. This seems rather dangerous to me. It's definitely making some > assumptions about how the particular compiler implements things. It's also > not clear this is really a win in machine code. While the C source code > looks compact and possibly efficient at first glance, it could expand into > more than hoped. > > The first thing that makes me wonder is what the effect is of entering a DO > loop in the middle. Since in this case the decision is performed at the > end, maybe it's OK. Does the C definition really promise that no hidden > initialization or whatever be written by the compiler at the beginning of > the DO? I expect not, but am not a C whiz. I can see most compilers > probably don't do anything special there, but I still suspect this is > compiler-specific code. > > As for efficiency, the initial jump into the loop may not be so great. > Compilers typically use a jump table or successive IFs to jump to the > selected case. The tradeoff depends on the number of cases and the > overhead > of indexing into a jump table in the underlying machine language. Eight > cases is probably enough to result in a jump table, but even that can have > significant overhead depending on the machine. If you were writing this in > PIC assembler, you'd probably notice that each case is the same length and > do a relative jump forward by a multiple of the case size. I rather doubt > a > compiler writer would have bothered to check for the special instance of > all > cases being the same size and sequential and then computing the relative > jump offset directly. > > So while Duff's device may look cute in C, I don't think it's something you > really want to put in your code. You're better off with a loop that does > blocks of 8 transfers followed by a loop or SWITCH that does the remaining > fraction. Depending on the overhead of indexing into a jump table and what > the remaining fraction turns out to be at run time, it's not clear whether > a > loop or a SWITCH would be faster for the remaining transfers. > > > C's default fall-through in case statements has long been its most > > controversial single feature; Duff observed that "This code forms some > > sort of argument in that debate, but I'm not sure whether it's for or > > against."[1] > > I've met Tom Duff, and he's a smart guy. This shows that even he isn't so > sure this is a good thing to recommend. I think he was working on a PDP-11 > at the time. He probably knew enough about the instruction set and his > particular compiler to know it would work well in his case. > > > ******************************************************************** > Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products > (978) 742-9014. Gold level PIC consultants since 2000. > -- > http://www.piclist.com PIC/SX FAQ & list archive > View/change your membership options at > http://mailman.mit.edu/mailman/listinfo/piclist > -- http://www.mcuhobby.com -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
Re: using BREAK in 'C'On Mon, Jun 29, 2009 at 5:03 PM, Tamas Rudnai <tamas.rudnai@...>wrote:
> I am not sure if it is mandatory or not but in all C compiler I have seen > the switch-case was compiled either to series of if..goto or optimised in > the similar manner, like jump tables or checking range and a goto if there > was more than one case in series describing an entire range of literals. Now that I was thinking over of it, it should be mandatory... So as once you jump into a case C should continue the execution through all case statements till a break (or the end of the switch). Therefore inside the case there should be no "if" or "goto" put by the compiler. Hence the IF ... GOTO CASE1; IF ... GOTO CASE2; IF ... GOTO CASE3; CASE1: ... .. ... CASE2: CASE3: ... ... (or the jump table or equivalent) assembly structure out of the compiler... So it should be safe to use these kind of tricks -- might not nice as per reading the source though. Tamas -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
Re: using BREAK in 'C'> Marcel Birthelmer wrote:
>> Here's the example from Wikipedia (slightly modified for (my) >> readabilitiy): >> >> register n=(count+7)/8; >> switch(count%8){ >> case 0: do{ *to = *from++; >> case 7: *to = *from++; >> case 6: *to = *from++; >> case 5: *to = *from++; >> case 4: *to = *from++; >> case 3: *to = *from++; >> case 2: *to = *from++; >> case 1: *to = *from++; >> }while(--n>0); >> } > > Hmm. This seems rather dangerous to me. It's definitely making some > assumptions about how the particular compiler implements things. This is standard "C" and a conforming compiler must implement it correctly. > It's also > not clear this is really a win in machine code. As always, there are no promises of efficiency for any given high level structure (at least not in the standard, although a specific compiler might promise performance). However, most good compilers will generate very nice code from the above. >While the C source code > looks compact and possibly efficient at first glance, it could expand into > more than hoped. Again, a good compiler will do a decent job with this. > The first thing that makes me wonder is what the effect is of entering a > DO > loop in the middle. Since in this case the decision is performed at the > end, maybe it's OK. Does the C definition really promise that no hidden > initialization or whatever be written by the compiler at the beginning of > the DO? I expect not, but am not a C whiz. I can see most compilers > probably don't do anything special there, but I still suspect this is > compiler-specific code. Again, this is standard code. If some initialization code is required it is the compilers job to ensure it gets called. However, I believe, though I am not sure, that the standard does not require initialization of variables local to the loop if the start of the loop is skipped over. This is a bad thing (tm). > As for efficiency, the initial jump into the loop may not be so great. > Compilers typically use a jump table or successive IFs to jump to the > selected case. The tradeoff depends on the number of cases and the > overhead > of indexing into a jump table in the underlying machine language. Eight > cases is probably enough to result in a jump table, but even that can have > significant overhead depending on the machine. If you were writing this > in > PIC assembler, you'd probably notice that each case is the same length and > do a relative jump forward by a multiple of the case size. I rather doubt > a > compiler writer would have bothered to check for the special instance of > all > cases being the same size and sequential and then computing the relative > jump offset directly. The important thing is that the performance of the first iteration isn't all that important. It is just a convenient way to get the loop started. -- Bob Ammerman RAm Systems -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
Re: using BREAK in 'C'Bob Ammerman wrote:
>> case n: is just a label, that is why it has the colon after it (just >> like any other label in C). That is also why the break leaps out of >> the switch statement, just like it jumps out of a while or for >> statement. > > 'case n:' is *not* a label. It *cannot* be the target of a goto. FWIW, both the C89 and C99 specs refer to it as "case label". However, I can't find (anymore?) the place where I thought the C99 standard allowed case labels as targets for goto. Must have dreamed that... Sorry for the confusion, Gerhard --------------------------------------------- C89 spec: 3.6.1 Labeled statements Syntax labeled-statement: identifier : statement case constant-expression : statement default : statement Constraints A case or default label shall appear only in a switch statement. Further constraints on such labels are discussed under the switch statement. -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
Re: C programs representationLuis Moreira wrote:
>> Doxygen > > This does not seem to be what I am looking for. What I need is > something that will allow me to produce something similar to a class > diagram. Do you mean a call graph? Doxygen can generate this for you. Have you tried, or read the documentation? <http://www.stack.nl/~dimitri/doxygen/diagrams.html> If this is not it, what do you want? Gerhard -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
RE: C programs representationHi Gerhard,
You are right, this is probably what I need. I never realised how difficult it was to get a relationship diagram in C that gives you all the information about the function interaction. But maybe is the way I am writing my programs. I started out by having a separate file for each function that I deemed it was large enough or had some possibility of reuse, but then it seem to make more sense to have library C file that had all the functions in it. Like this I just include one file and all the functions are there. At this point it doesn't seem like a good idea anymore. Thanks Luis -----Original Message----- From: piclist-bounces@... [mailto:piclist-bounces@...] On Behalf Of Gerhard Fiedler Sent: 29 June 2009 20:59 To: Microcontroller discussion list - Public. Subject: Re: [EE] C programs representation Luis Moreira wrote: >> Doxygen > > This does not seem to be what I am looking for. What I need is > something that will allow me to produce something similar to a class > diagram. Do you mean a call graph? Doxygen can generate this for you. Have you tried, or read the documentation? <http://www.stack.nl/~dimitri/doxygen/diagrams.html> If this is not it, what do you want? Gerhard -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist |
|
|
|
| < Prev | 1 - 2 - 3 | Next > |
| Free embeddable forum powered by Nabble | Forum Help |