v1.50-4.00 bèta:Same code, different results?

Beta Testing discussion on mikroPascal PRO for PIC.
Post Reply
Author
Message
Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

v1.50-4.00 bèta:Same code, different results?

#1 Post by Dany » 23 May 2009 19:35

Hi, I encountered again some very strange phenomenon: 2 pieces of code look exactly the same, but give total different results. In the examples below I try to calculate 60% of 3968 (which is -truncated- 2380) in global variable Wrd2.

This is what happens:

Code: Select all

program Type_Casting_cont;
var Wrd1, Wrd2: word;
    Percentage: byte;

procedure Proc(TotalMemSize: word);
var I: byte;
begin
  // ------------ test ------------- //
  Wrd1     := 3968; // line X
  Percentage := 60; // line Y
  Wrd2    := Wrd1 * Percentage div 100;         // Wrd2 = correct (2380)
  Wrd2    := TotalMemSize * Percentage div 100; // Wrd2 = faulty (414)
  // ------------ end test ------------- //
end;

begin
  Proc(3968);
end.
As you can see, in both cases the calculation done is 60% out of 3968, once with a global variable (Wrd1), once with a parameter (TotalMemSize) holding the value 3968.

There is more: If I move line X or line Y or both to the main function (just before the call to Proc, then both calculations give the value 414!

So, this code

Code: Select all

program Type_Casting_cont;
var Wrd1, Wrd2: word;
    Percentage: byte;

procedure Proc(TotalMemSize: word);
var I: byte;
begin
  // ------------ test ------------- //
  // Wrd1     := 3968;
  Percentage := 60;
  Wrd2    := Wrd1 * Percentage div 100;         // faulty  (414)
  Wrd2    := TotalMemSize * Percentage div 100; // faulty  (414)
  // ------------ end test ------------- //
end;

begin
  Wrd1     := 3968;  // if placed here, both calculations are wrong
  Proc(3968);
end.
gives always the wrong value in Wrd2.


Wierd eh?
p.s. not so wierd (I had a look to the listing now): in the "correct" case the compiler did not use the variables Wrd1 and Percentage, it simply used the value constants assigned to them (a code optimisation, called "Constant propagation" in the helpfile).
In the other cases it used the variables, and then the calculation method is different and only correct if the left hand side variable can hold the intermediate result (=DWord), or explicite typecasting is used:

Code: Select all

Wrd2    := Dword(TotalMemSize * Percentage div 100);
Which looks weird on its own (typecasting to a a DWord while the receiving var is a word -- I know Florin --).

p.s. Still looks weird afterall. The mP programmer can not know how the compiler will calculate things (how the code will be optimised), and pascal code that looks the same should give the same result. Optimisation should never show side effects to the user! Here the different calculation/typecasting rules for constants and variables are the reason.
Last edited by Dany on 06 Aug 2010 12:43, edited 13 times in total.
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

Kalain
Posts: 1093
Joined: 11 Mar 2005 18:26
Location: Aubenas, France

#2 Post by Kalain » 24 May 2009 08:47

Hi,

seems also to meet this problem. (Lasts posts;)
http://www.mikroe.com/forum/viewtopic.php?t=20149
Alain

Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

#3 Post by Dany » 24 May 2009 08:59

Kalain wrote:Seems also to meet this problem. (Lasts posts;)
http://www.mikroe.com/forum/viewtopic.php?t=20149
Indeed! Thanks.
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

User avatar
srdjan
mikroElektronika team
Posts: 1552
Joined: 28 Dec 2005 12:47
Location: Serbia

Re:

#4 Post by srdjan » 17 May 2010 10:05


Post Reply

Return to “mikroPascal PRO for PIC Beta Testing”