Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C := A +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+B;

10 views
Skip to first unread message

Skybuck Flying

unread,
May 1, 2022, 7:36:08 PM5/1/22
to
Can asm do this crazy stuff too ?


program TestProgram;

{

Test +-+-+-+-+-+-+-+ plus minus plus minus plus in Delphi

version 0.01 created on 2 may 2022 by Skybuck Flying

I came across this weird code and it actually compiles.

It actually led to a bug when trying to draw a vertical line and Delphi compiler
did not catch it, no hint, no warning, nothing.... let me show you,
it was in opengl but I will show the same effect with vcl canvas methods:
(this happened because the opengl screen/coordinate system was translated
to make the origin 0,0,0 at the center of screen, so imagine a canvas that
somehow does that as well, otherwise imagine opengl vertex call, I will show
both:


openl code:
glVertexf( X, -ScreenHeightHalf );
glVertexf( X, +-ScreenHeightHalf );


vcl code:

MoveTo( X, -ScreenHeightHalf );
LineTo( X, +-ScreenHeightHalf );

The code above is flawed, because the negative sign wins... so
it will infact draw no line at all !

Which is kinda difficult to see, because it requires understanding the precedence
of operators, which operator will win, what are the rules.

Is there an left to right, or right to left rule, or is it just math rules... like
negative wins over positive, or vice versa... hmmmmmm.

Not sure... is it undefined... not sure...

What happened is, as I copied the code from line 1 to line 2, I placed a plus
in front of it, but forgot to illiminate the negative sign and surprise
surprise it actually compiled ! Which leads to the following funny test code
which I also immediately tried and strangely enough it compiles without
any hints or warnings...

It would have been nice if Delphi could catch this situation, and maybe
at least give some kind of hint or warning messages, I think a hint would
be sufficient...

I am also curious what kind of code/assembly is generated and also if this
code ports to c/c++ and other languages, and if other compilers
give any warnings what so ever.


}

{$APPTYPE CONSOLE}

{$R *.res}

uses
System.SysUtils;

procedure Main;
var
A, B, C : integer;
begin
writeln('program started');

A := 50;
B := 25;

// C := A + B; // produces 75
// C := A +- B; // the bugged code, produces 25

// nice obfuscation ! =D and that in Delphi/Pascal ?! HOLYFUK.
// C := A +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-B; // the funny code produces 75
// C := A +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+B; // still produces 75, how ? strange ?

// My hypothesis about what is going on above: Limited compiler operator room/buffer/processing ?
// I am starting to suspect that maybe the compiler has a limited ammount of operators that
// it can handle ?!? Is this the thruth ? I don't know yet.
// nope doesn't seem to be case see below:

// last one wins on the left side ?
// C := A -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+B; // produces 25.


// another case of insane code:
// C := A ------------------------------------------------------B; // produces 75.

// now it does produce an error
// C := A -+*******-----+++----********* B; // error

// C := A ******** B; // error

// C := A / / / / / B; // error

// C := A -- B; // produces 75
// C := A --+ B; // produces 75
// C := A -+- B; // produces 75
// C := A +-- B; // produces 75

// C := A --- B; // produces 25
// C := A ---+ B; // produces 25


// C := A +-+-+-+ B; // produces 25
C := A +-+-+-+-+ B; // produces 75

// to solve it, count the number of negatives... unequal it will subtract equal it will add.
// (cause the negatives negate each other into positive)


writeln( A );
writeln( B );
writeln( C );

writeln('program finished');
end;

begin
try
Main;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
ReadLn;
end.

Skybuck Flying

unread,
May 1, 2022, 10:05:23 PM5/1/22
to
Update, looked at some other cases as well, it does optimize for plusses, not for negates:
STRANGELY ENOUGH DELPHI COMPILER DOES NOT OPTIMIZE THIS SITUATION, IT JUST
PRODUCES A BUNCH OF NEGATES.

WEIRD OR WHAT... MAYBE IT'S THE LLVM COMPILER...

IS THERE A REASON FOR THIS ? MAYBE TO ALLOW RACE CONDITIONS OR TIMING CODE
TO BE WRITTEN LIKE THIS ?

IS REDUCING IT TO A SINGLE NEGATE NOT "LOGICALLY EQUIVALENT"

MAYBE PHYLOSOPHICAL ISSUE... OF "EQUIVALENCY"... TIME WISE HEHE.

MAYBE IT IS JUST AN OVER SIGHT, OR A MISSED OPPERTUNITY TO OPTIMIZE.


OR MOST LIKELY... THIS KIND OF CODE IS SIMPLY VERY RARE... MOSTLY CONSIDERED

A PROGRAMMING MISTAKE... AND THEREFORE THERE IS NO OPTIMIZATION FOR THIS...

SO THIS KINDA HINTS AT, THAT WHO-EVER WROTE THE COMPILER CONSIDERS THIS
EXOTIC/STRANGE/RARE/STRANGE/ODITY/CURIOSITY CODE AND
THAT KINDA WARRENTS A HINT OR EVEN WARNING MESSAGES
THAT THE COMPILER DETECTED SOMETHING STRANGE !

}

{$APPTYPE CONSOLE}

{$R *.res}

uses
System.SysUtils;

procedure Main;
var
A, B, C : integer;
begin
writeln('program started');

A := 50;
B := 25;

// C := A + B; // produces 75
// C := A +- B; // the bugged code, produces 25

// nice obfuscation ! =D and that in Delphi/Pascal ?! HOLYFUK.
// C := A +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-B; // the funny code produces 75
// C := A +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+B; // still produces 75, how ? strange ?


// NOT OPTIMIZED BY COMPILER.
// C := A -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+B; // still produces 25


// C := A ------------------------------------------------------B; // produces 75

// DOES SEEM TO BE OPTIMIZED BY COMPILER.
// C := A ++++++++++++++++++++++++++++++++++++++++++++++++++++++B; // produces 75

// C := A ++++++++++++++++++++++++-+++++++++++++++++++++++++++++B;

// IT DOES SEEM TO DO SOME KIND OF OPTIMIZATION, BUT ONLY FOR PLUSSES ?! NOT MINUSSES ?!? WHY ?!
// ISN'T THAT A BIT INCONSISTENT ?
// MAYBE BECAUSE NEGATE INFLUENCES THE FLAGS ?!?!?
// WHY DID COMPILER WRITERS TAKE THIS DECISION TO NOT "OPTIMIZE WAY MULTIPLE NEGATES"
// THAT IS WHAT I WOULD LIKE TO KNOW...........................
C := A ++++++++++-+++++++++++++-+++++++++++++-+++++++++++++++B;


// My hypothesis about what is going on above: Limited compiler operator room/buffer/processing ?
// I am starting to suspect that maybe the compiler has a limited ammount of operators that
// it can handle ?!? Is this the thruth ? I don't know yet.
// nope doesn't seem to be case see below:

// last one wins on the left side ?
// C := A -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+B; // produces 25.


// another case of insane code:
// C := A ------------------------------------------------------B; // produces 75.

// now it does produce an error
// C := A -+*******-----+++----********* B; // error

// C := A ******** B; // error

// C := A / / / / / B; // error

// C := A -- B; // produces 75
// C := A --+ B; // produces 75
// C := A -+- B; // produces 75
// C := A +-- B; // produces 75

// C := A --- B; // produces 25
// C := A ---+ B; // produces 25


// C := A +-+-+-+ B; // produces 25
// C := A +-+-+-+-+ B; // produces 75

// to solve it, count the number of negatives... unequal it will subtract equal it will add.
// (cause the negatives negate each other into positive)


writeln( A );
writeln( B );
writeln( C );

writeln('program finished');
end;

begin
try
Main;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
ReadLn;
end.

Bye for now,
Skybuck.

P.S.: My internet service provider cut the connection as I was investigating this issue and reporting on it... now I have moved on... but I will check replies anyway ofcourse ! ;)
(ISP let me know this was gonna happen so no worries ! ;)=D they working on NET)

Meanwhile I found some other interesting issues like 0 * infinity = -NAN... more interesting issue for me currently... see you later ! ;)
0 new messages