\NOT A BUG/: File I/O functions / Display -- Nevermind.

Started by monkey0506, Tue 17/07/2007 20:37:21

Previous topic - Next topic

monkey0506

Trying to display multiple characters back from a file at once, I discovered what would appear to be a bug. I did this:

Code: ags
File f = File.Open("file.txt", eFileWrite);
f.WriteRawChar('x');
f.WriteRawChar('y');
f.WriteRawChar('z');
f.Close();
f = File.Open("file.txt", eFileRead);
Display("read back: %c, %c, %c", f.ReadRawChar(), f.ReadRawChar(), f.ReadRawChar());
f.Close();


The expected output of course being:

read back: x, y, z

However the actual output I got was this:

read back: z, y, x

Splitting the single Display statement into three gave me the output I expected, printing out the letters in the desired order.

If anyone could shed any light on why this behaviour takes place it would be greatly appreciated. Until then I can simply split up my output.

Scorpiorus

The thing is that the parameters to pass into Display is evaluated from right to left, so the last f.ReadRawChar gets called first which returns "x"; next "y", and finally "z":

Display("read back: %c, %c, %c", f.ReadRawChar(), f.ReadRawChar(), f.ReadRawChar());

monkey0506

I didn't know that Display's parameters were evaluated right to left. :o Is this documented somewhere? Or just one of those things that only "t3h 3L173" know about?

Pumaman

It's nothing special about the Display command, it's just the standard way that function calls are done. The parameters to all function calls are evaluated right-to-left, so that's the reason for the effect you are seeing.

monkey0506

I had no idea...well...nevermind then I guess.

Monsieur OUXX

Quote from: Pumaman on Tue 17/07/2007 21:03:56
The parameters to all function calls are evaluated right-to-left

Even with String.Format(...) ?
The output above would have been the same with the code below?

Code: ags

Display(String.Format("read back : %c %c %c", f.ReadRawChar(), f.ReadRawChar(), f.ReadRawChar()));
 

Gilbert

Yes I think it would be the same, as the rule should apply to arbitrary function calls (like blah(f.ReadRawChar(), f.RawReadChar()) ). So the most secure method is to use something like:
Code: ags

a=f.ReadRawChar();
b=f.ReadRawChar();
c=f.ReadRawChar();
Display(String.Format("read back : %c %c %c", a, b, c);

Scorpiorus

Yeah it's all about the order in which function parameters are pushed into a stack -- last parameter goes first, so it must be evaluated first as well.

Code: ags

function test( int, int, int )
{

}

...

test( Display("1"), Display("2"), Display("3") );


...and the output will be: 3, 2, 1

This is known as a "cdecl" calling convention used by default in many "C" compilers, which besides that order also specifies the rules on how a stack memory is freed -- which makes it possible to support variable number of arguments passed into a function (eg: Display(string, ...) ).

SMF spam blocked by CleanTalk