Search | | Contact Us | Resource Center Login | Home|

If the file named "pragprog.txt" contains the text from the preface to The Pragmatic Programmer: From Journeyman to Master, by Andrew Hunt and David Thomas (Addison-Wesley, Oct 1999), then what is the output of the following program?

    intro ,a80
            xcall get_line(3, intro)
            writes(1, %atrim(intro))
    catch (e, @Exception)
        writes(1, "tl;dr")
    close 2
function get_line, ^val
in req channel    ,int
out req buffer    ,a
    reads(channel, buffer) [err=err]
    freturn 1
    freturn 0

a. “You really need to read this book!”

b. “This book will help you become a better programmer.”

c. “tl;dr”

d. a blank line

Correct answer: (d)


The first line of the preface of the book in question matches answer (b), but it appears that answer (a) may be more suitable for the author of this program.  The second OPEN statement specifies an I/O mode of "o" for "output", so the first time it is run it overwrites the precious preface with an empty file.

Not only does this program open the file in output mode, but it also passes the wrong channel to the "get_line" function.  This channel (3) hasn't been opened, so the READS statement fails.  The function returns zero in that case, but the main program doesn't test for that.  Instead it attempts to detect failure with a TRY/CATCH pair.  But since the function never throws an exception, the TRY/CATCH is useless.  Thus, the program goes ahead and spits out the unmodified contents of the field "intro", which will be space-filled in this case due to default initialization of records in main routines in Synergy/DE.  Thus, (d) is the correct answer.

If this field had been a member of a stack record, its contents would be undefined.  That would be a potential security vulnerability, because it could contain previously accessed data that shouldn't be revealed to the user.

We can draw the following lessons from this example:

1.  When calling a function, make sure you understand how it handles exceptional cases, and don't ignore them.

2.  Don't use literals for channel numbers (or anything else).  When you change one place where it's used, you'll forget to change another.

3.  Always test your code using expendable or recoverable data.

4.  If you haven't yet, go read The Pragmatic Programmer!

More information about News and Events

Contact Synergex to learn more about  News and Events