Istanbul Bilgi University Department of Computer Science
Previous Home > Curiosity Corner > Questions And Answers > Order Of Evaluation Of Parameters Next
Home
   About This Site
   Academic Policies
   Academic Staff
   Courses
   Curiosity Corner
      Challenges
      Days Of The Week
      Hardy And Ramanujan
      Les Sept Cartes Mysterieuses
      Polya - How To Solve It
      Questions And Answers
         Order Of Evaluation Of Parameters
      Wilkes At 90
   High School Computer Clubs Project
   Lab Rules
   Links
   Member Help
   News
   Other Stuff
   Standards Project
   Tanitim
   Turing Days
   Usage Statistics
   Yarışma

Order of evaluation of parameters

(Now with solution)
 

Göker Göksel wrote:


> I was writing a program and realized something for the
> first time. I had a function with 2 parameters like
> this:
>
> removeDuplicate(getString_Mes("Input file: "),
> getString_Mes("\nOutput file: "));
>
> char * getString_Mes(char *);
> void removeDuplicate(char *, char *);
>
> what it does is simple. it gets 2 strings which in
> this case are filenames and sends them to the
> removeDuplicate function.
>
> when I executed the program, I realized that the
> second 'getString_Mes' was executed first.
> Is this the way the compiler compiles the program?
> does is it work bacwards?
 

Chris Replied


Yes an interesting problem - and sometimes a very important one, leading
to difficult-to-solve bugs.

The C compiler offers NO GUARANTEE about the order of evaluation of the
parameters for a function call. It doesn't guarantee the order of
evaluation of expressions, either, EXCEPT expressions like (a && b),
where the evaluation is guaranteed to be from left to right. (You might
like to think about the reason for that - think about while ((a != NULL)
&& (strcmp(a,"endmarker"))) - what would happen if we could not
guarantee the order of evaluation? In languages where that order is NOT
guaranteed you are forced to write that program rather differently...

In fact if the C calling convention is used the parameters will USUALLY
be evaluated right to left. However if you set up the compiler to use
the Pascal calling convention for that procedure (the way to do that
differs from compiler to compiler), then the parameters will USUALLY be
evaluated left to right. This can cause EXACTLY the same program to give
different results, depending on a compiler option. Very confusing.

This is a good example of a general programming problem - side effects
of functions.

We say a function has side effects if it changes the value of something
outside its own scope. This can be a global variable, something pointed
to by a parameter or, as in your case, an external file (which is also a
global thing). The problem with side effects is that they create
unpredictable programs. As you have just found out!

Some languages try to eliminate this by banning side effects completely.
You can really only do this if you have a garbage collected memory
scheme as you end copying data structures all the time. (The ban on side
effects makes it impossible to modify structures in called functions -
the function has to create a modified copy and return that in order to
obey the rules.) Such languages are generally used for theoretical
studies or where reliability and proveability take precedence over
performance.

Of course for your program, there is a simple cure. Make the getstring
calls first, then call removeduplicate. That way you know the exact
order that all the calls will be made.

Now. I took the time to write you this longish reply. Can you make me a
nice example program and a little write up showing this problem (the
called function can simply write to the screen, for instance) and
showing the effect of switching to the Pascal calling convention??

Then let us put this correspondence up on the website in a programming
FAQ section...

Happy programming!

Chris Stephenson

By the way, why is the C calling convention different from a language
like Pascal? Because it supports function calls (like printf) with
VARIABLE numbers of arguments. If you think about the way the stack
frame is formed, then you will see that this the reason why the last
arguments are towards the bottom of the stack (and are therefore put on
FIRST). Otherwise the called function would not be able to know where
the first argument was...
 

Göker's example program:


Download it here

Göker wrote:
I wrote a small program for the difference between
pascal and c calling conventions. I wrote a paragraph
(a long one) of explanation. if you find it
unsatisfactory, I can write another one, but i think
it is simple and easy to understand. I found a few
things on the net about calling conventions. they are
just small bits of information about calling
conventions, but enough to give an idea.

http://www.eccentrica.org/Mammon/Text/stack_apj.txt
http://www.ctp.bilkent.edu.tr/~hinisli/AdvancedC.htm
http://www.neilstuff.com/index.php?p=55#Pascal_calling_convention

pages are too long. you might need to search for the
word 'convention'.