Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » Allegro and C++, platform dependence?

This thread is locked; no one can reply to it. rss feed Print
Allegro and C++, platform dependence?
Peter Hull
Member #1,136
March 2001

I've been looking at Johan's Bloobs * recently and there seems to be something strange going on with maths and trig.

In a nutshell, what would you expect the output of sin(i) to be, where i is an int? I would expect sin(double(i)). Other people seem to be getting sin(fix(i)) which is completely different. When I investigated it got weirder.

Would you mind compiling some of these mini-programs and letting me know what happens ?

These are C++ programs, source code attached.

Program 1:

#include <allegro.h>
#include <cstdio>
int main() {
  install_allegro(SYSTEM_NONE, &errno, atexit);
  int i=1;
  printf("%d\n", sin(i));
  return 0;
}END_OF_MAIN()

Program 2

#include <allegro.h>
#include <iostream>
int main() {
  install_allegro(SYSTEM_NONE, &errno, atexit);
  int i=1;
  std::cout<<sin(i)<<std::endl;
  return 0;
}END_OF_MAIN()

Program 3

#include <math.h>
#include <allegro.h>
#include <cstdio>
int main() {
  install_allegro(SYSTEM_NONE, &errno, atexit);
  int i=1;
  printf("%d\n", sin(i));
  return 0;
}END_OF_MAIN()

I get
Program1: Won't compile - error: conversion from `int' to non-scalar type `fix' requested
Program2: 0.841471 (i.e. the sine of 1.0 radians)
Program3: 1072360788 :o I can only guess that it's calling sin(fix) and SYSTEM_NONE doesn't initialise the trig system?
This is on gcc 3.3, Mac OSX

Please could someone else give these a try?

Thanks

Peter

  • innuendo intended ;)

Mark Robson
Member #2,150
April 2002

Program1: won't compile
Program2: 0.841471
Program3:

Compiler warning
test3.cpp: In function `int _mangled_main()':
test3.cpp:7: warning: int format, double arg (arg 2)

But gives result
-1895232274

Which I guess is total rubbish.

Mark

da_flo
Member #1,907
February 2002
avatar

Program 1 :
prog1.cc: In function `int _mangled_main()':
prog1.cc:6: error: conversion from `int' to non-scalar type `fix' requested

Program 2 :
0.841472

Program 3 :
-1895232274

gcc version 3.3.1 (Mandrake Linux 9.2 3.3.1-2mdk)
Allegro 4.1.15

Peter Hull
Member #1,136
March 2001

I am an idiot :-[ thanks Mark! Program 3 should be
Program 3

#include <math.h>
#include <allegro.h>
#include <cstdio>
int main() {
  install_allegro(SYSTEM_NONE, &errno, atexit);
  int i=1;
  printf("%f\n", sin(i));
  return 0;
}END_OF_MAIN()

In which case i get 0.84..

But I still don't understand why, in the bloobs program, some people need math.h and some don't, and why some people are saying that the fix trig functions are being called?

Pete

X-G
Member #856
December 2000
avatar

Fix in Allegro is typedef'd to some sort of integer — signed long, I believe. There are also overloaded trigonometric functions for this type in C++. What then happens is that the compiler looks for which version of sin matches '1' (which is an int) most closely — and finds that since fix is really an int, that version matches best and bam — instant unexpected behaviour.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

da_flo
Member #1,907
February 2002
avatar

fixed is a typedef to an integer.
But fix is a c++ class which is a wrapper around fixed, and which overloads lots of operators and also some inline math functions such as trig functions. The overloaded functions simply call the allegro fix trig routines.

See include/allegro/fix.h and include/allegro/inline/fix.inl

X-G
Member #856
December 2000
avatar

Constructing a fix object from a fixed via the appropriate constructor is apparently ranked higher than casting to double, then.

--
Since 2008-Jun-18, democracy in Sweden is dead. | 悪霊退散!悪霊退散!怨霊、物の怪、困った時は ドーマン!セーマン!ドーマン!セーマン! 直ぐに呼びましょう陰陽師レッツゴー!

Elias
Member #358
May 2000

Is this with 4.0.3 or 4.1.16?

With 4.1.x, the sin function was changed somehow (I think using "explicit" - but I don't know much about C++) so you should always get the expected behavior, and even a warning that "fixed" is used when you forget to include math.h. (In 4.0.3 it wasn't changed so old programs who used the fixed sin would keep compiling.)

--
"Either help out or stop whining" - Evert

Peter Hull
Member #1,136
March 2001

I have 4.1.16. This may be making sense now, what do you think?

If math.h is not included, but allegro.h is, the compiler interprets
sin(an_int) as sin(fix(an_int)) using the constructor fix::fix(int), and calls fix sin(fix)

If both math.h and allegro.h are included, the compiler picks a 'better' conversion
sin(double(an_int)) and calls double sin(double)

For 4.1.16 folks, the fix::fix(int) constructor is marked 'explicit', so the compiler won't call it automatically, and gives the error that we saw.("error: conversion from `int' to non-scalar type `fix' requested")

For 4.0.x, it's not marked explicit so it can be called automatically.

It seems that math.h might or might not be included, depending on the platform (it may be included from within another header file)

Therefore, for Allegro 4.0.x, sin(1) might be 0.84 (sine of 1 radian) or 0.02 (sine of 1 allegro degree== 360/256 normal degrees)

Moral of the story - You should cast integer arguments of sin, cos etc to double explicitly, to be certain that it will give the expected results.

Pete

da_flo
Member #1,907
February 2002
avatar

But anyway I think that the allegro fix class and above all the trig function overloading can really be an annoyance sometimes, and I think it must confuse lots of newbies ( and even not-so-newbies )...

Go to: