[Skip Navigation] [CSUSB] / [CNS] / [Comp Sci & Eng] / [R J Botting] /[CS320 Course Materials] [Text Version] lab/09.html Tue May 4 19:40:19 PDT 2010
Labs: [01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20]

Contents


    CSci320 Programming Languages -- laboratory 09 -- C++ Control structures

    Duff's Disgusting Device

    Look at this [ 66008138e07aa94c?q=Duff+group:net.lang.c.* ]

    Duff's original code assumes that the place that the data is being moved to is not RAM but an address of a peripheral! When run with "to" pointing at RAM it needs a fix. I am grateful to an alert reader who corrected me:

     > Given the "8 times", I think you're considering the "*to" (instead
     > of "*to++") being an error.
    [As was]
     >
     > May I point out that Tom Duff's application of that routine was to
     > send data to a device register which was memory-mapped at a fixed
     > address, so his code is (for *his* application) correct? This is
     > explained in Duff's original posting[2] as well as (slightly more
     > elaborate) a later comment[3].
     >
     > Of course, the application (memory-to-memory copy vs.
     > copy-to-device-register) is orthogonal to Duff's discussion
     > of language properties.
     >
     > Regards,
     >  Ignatios Souvatzis

    Here is a complete working program in C [ ../c/duff.c ] that uses this device to copy integer arrays.

    What changes must you make to move from C to C++?

    Notice that it uses a C function header that expects you to provide the address of two arrays: write a main program that lets you test it.

    Publish your working C++ code and link it to a lab page explaining what is good and bad about Duff's device.

    By the way, people [ search?q=%22duff%27s+device%22&start=0&scoring=d&hl=en&lr=&safe=off&num=10 ] are still discussing this trick.

    Jackson's Inversion

    Here is the design of a co-function that accepts a series of integers and detects the first and later occurence of the number 2:
  1. input::= #(int~2) 2 #(int~2).

     string fun(int i)
     {
     	restart();
     	while( i != 2)
     	{
     		resume "no two yet";
     	}
     	resume "two";
     	while(true)
     	{
     		resume("there was a two");
     	}
     }
    Unfortunately the above uses restart() and resume() which are nonstandard C++ functions. Resume exits a function but remembers where it was, and restart goes to that place the next time the function is call. So here is a sample test run
    Table
    ireturned value
    1no two yet
    3no two yet
    2two
    1there was a two
    2there was a two
    3there was a two

    (Close Table)
    M. A. Jackson publicised a way to use switch, goto, etc to implement restart and resume.

    Here is a file that shows it coded in standard C++. Download, compile, run and test... [ ../restart.cpp ] Download, compile, and test (99 is the terminating sentinal for input...). If you have time you can try changing it...

    Add to your web page a comment on this style of "inverted code" plus a link to an example.

    Evil C Macros to make Co-Routines

    Co-routines are an alternative way of getting the same effect as Jackson's inverted code. Here [ coroutines.html ] is a link into a way to get the same effect in C by using some possible dangerous macros. It also has a good discussion of why we need co-routines.

    Check the Preparation for next class

    [ ../10.html ]

    If you have time

    [ wiki?ProgrammerLiteracy ]

End