hello,
I'm trying to make a game with allegro, and I need threads. I've found the boost library but it seems that there is a problem between allegro and boost ...
when I build my project I've got this kind of errors :
1>c:\program files\boost\boost_1_38\boost\cstdint.hpp(193) : warning C4114: même qualificateur de type utilisé plusieurs fois
1>c:\program files\boost\boost_1_38\boost\cstdint.hpp(193) : error C2632: 'char' ne peut pas être suivi de 'char'
1>c:\program files\boost\boost_1_38\boost\cstdint.hpp(193) : warning C4091: 'typedef ' : ignoré à gauche de 'signed char' quand aucune variable n'est déclarée
1>c:\program files\boost\boost_1_38\boost\cstdint.hpp(196) : warning C4114: même qualificateur de type utilisé plusieurs fois
that only do it when the include of allegro is before the boost one ...But I don't know how to control exactly the order of inclusion in my project (I've got a lot of class using both allegro and boost ...)
Has someone a solution to solve this or does anyone know an other library for thread ?
(and excuse me for my english ...^^')
An alternative to boost is POSIX threads, which POSIX compliant operating systems should support natively. It is definitely present in Linux, and I assume it would be also on Mac (though I am not sure). There is a port for Windows here.
1> c: \ program files \ boost \ boost_1_38 \ boost \ cstdint.hpp (193): warning C4114: same type qualifier used more than once
1> c: \ program files \ boost \ boost_1_38 \ boost \ cstdint.hpp (193): error C2632: 'char' can not be followed by 'char'
1> c: \ program files \ boost \ boost_1_38 \ boost \ cstdint.hpp (193): warning C4091: 'typedef': ignored on left of 'signed char' when no variable is declared
1> c: \ program files \ boost \ boost_1_38 \ boost \ cstdint.hpp (196): warning C4114: same type qualifier used more than once
I've never used Boost's threads, but I have used Boost's smart pointers and some string algorithms... Never had problems, but I'm not sure if cstdint.hpp would have been necessary for those things. I'm downloading the 1.38.0 source to take a look at those lines to guess what might conflict from Allegro, if anything...
** EDIT **
There is no line 193 or 196 in cstdlib.hpp... And Boost organizes their code into a boost namespace, so it shouldn't conflict with a C library. Maybe you're doing something wrong including it? Maybe if you show us some code or how you organize your project we can figure it out?
I don't know... Hopefully somebody more experienced will come along.
cstdint.hpp, not cstdlib.
This is pretty much a lesson in why you always, always, always should use typedefs for types instead of #defines.
In Allegro's astdint you have:
#define int8_t signed char #define uint8_t unsigned char
So then boost's cstdint implementation attempts to do:
typedef signed char int8_t; // line 193 typedef unsigned char uint8_t; // line 196
But unforunately the compiler sees
typedef signed char signed char; typedef unsigned char unsigned char;
Oopsie.
there si a sample of my code :
this is my class Construction, I use this class for inheritance (I'm not sure this is the right word but ...) within it I need 2 mutex so:
#ifndef CONSTRUCTION_H
#define CONSTRUCTION_H
//the probleme include
#include <boost/thread/mutex.hpp>
#include "Listing.h"
#include "AVector.h"
class Construction
{
//datas and functions, no need to detail here ...
};
#endif
in another file (.cpp) I've got :
#include <allegro.h> //this is for drawing BITMAP and other function
#include "Construction.h"
and here : problem ...
I have supposed that it was a compability problem because when I try in a new file with :
#include <allegro.h>
#include <boost/thread/mutex.hpp>
it bug ...but in the other order :
#include <boost/thread/mutex.hpp>
#include <allegro.h>
it works fine (the problem then is the inclusion of my file with boot in the other...)
EDIT :
ok for the explanation thank you ... have you got a solution to avoid this?
cstdint.hpp, not cstdlib.
Ah, my bad.
have you got a solution to avoid this?
I think you should be able to work around it by #undef'ing the troublesome macros between includes (AFAIK, those macros are internal and not needed by external code)...
#include <allegro.h> #undef int8_t #undef uint8_t ... #include "Construction.h"
You'll have to see if it works or wait for somebody to correct me. Perhaps somebody should patch Allegro to use typedefs instead of macros. Or to at least use more unique names (
perhaps Allegro 5 is already doing this? No, no, it's still there...).
I'd probably just make a little wrapper for the allegro header:
#ifndef ALLEGROWRAPPER_H_INCLUDED #define ALLEGROWRAPPER_H_INCLUDED #include <allegro.h> #undef int8_t #undef uint8_t #undef int16_t #undef uint16_t #undef int32_t #undef uint32_t #undef intptr_t #undef uintptr_t #endif
Then #include AllegroWrapper.h in your files.
it works !!! thank you very much !!!^^
I hav had to add this lines too :
#undef intmax_t
#undef uintmax_t
#undef int64_t
#undef int_least64_t
#undef int_fast64_t
#undef uint64_t
#undef uint_least64_t
#undef uint_fast64_t
but now it works fine and allegro is always ok ^^
thanks both of you ^^
I'd probably just make a little wrapper for the allegro header:
That's exactly why the #defines are used..
That's exactly why the #defines are used..
Er... Use an incorrect method so that people will be able to fix the problems caused by use of said incorrect method? Does not compute.
Just do it right to begin with - a few lines of code in astdint.h and a few minutes with a halfway decent refactoring tool would fix the whole problem.
Ok, how do we do it right? Library A and library B both want to "typedef unsigned int uint32_t;". How can a user include both their headers without a conflict? I'm open to suggestions.
Instead of overwriting the standard types, you create your own types which wrap around them - you don't clash with the standard names so it doesn't matter if the user has a 3rd party implentation of those standard types.
Change astdint.h to be along the lines of:
And refactor existing code to use the new types.
Well that's the path of least resistance that everybody takes, and it's a bloody pain. Now I could understand it before C99 but that standard is ten years old now (or close to it). The problem is MSVC. Screw 'em.
Well that's the path of least resistance that everybody takes, and it's a bloody pain.
Hell, I just did the work for you and it took me all of one minute. Gonna have to go rest now after that strenuous exertion.
The problem is MSVC. Screw 'em.
You know, if you really wanted to be a lazy sod you could just undef all the macros at the end of allegro.h. But I guess then you couldn't take your awesome stand against teh evil Microsoft.
Of course it's easy to rename stuff inside the Allegro tree. I could do it in a couple of minutes. It's every damn library defining it's own types, and then the user needing to decide which ones to use where and whether they actually are all equivalent. Isn't that what the standard is for?
I'd probably keep the current behavior and add something like:
#define ALLEGRO_NO_STD_TYPES #include <allegro.h>
I think in C++ the typedefs make sense, where redefining the same type is allegedly supposed to be standard. However, in C, that's non-standard and can't be relied upon so the macros are the only way to get it done in a somewhat standard way. I don't think there's any harm in typedef'ing your own internal types though either. It would certainly be nice to have standard types to use in the games written in Allegro, but those should technically be coming from the platform, not a game's library. So for those platforms that don't have them (I got the impression it's just MSVC), you're stuck redefining them again. I find it a little awkward to have Allegro define things that I wouldn't expect it to and standard types fall into that category.
Of course it's easy to rename stuff inside the Allegro tree. I could do it in a couple of minutes. It's every damn library defining it's own types, and then the user needing to decide which ones to use where and whether they actually are all equivalent. Isn't that what the standard is for?
That's just a laughable argument. No one is relying on Allegro to define integer types for them (nor should they be). The entire problem here is that you're taking things that are for internal use and exposing them to the user, resulting in behavior that the user does not expect (redefinition of standard types).
those macros are internal and not needed by external code
So the user is not supposed to rely on them.
In my opinion, if <allegro.h> adds macros to compensate for something that is "missing" in some combination of conditions (nested #if), then at the of <allegro.h>, in the same conditions, it should remove it.
The problem is that Allegro can't undefine them at the bottom of it's header file(s) because I'm sure the Allegro header files are also needed by Allegro's source files, which probably expect those macros to still exist. The only way for Allegro to remove them is to create a user-space header file that wraps around the original, as Speedo suggested earlier. That, or just define Allegro specific types that are unlikely to collide so this problem isn't likely to come up.
Argh, then yes it's not a minor change.
Out of curiosity, anybody knows if Boost's typedefs for the uint* types also "leak out" ? Or are they "kept in containment" by the namespace ?
They reside in the boost namespace.
That's just a laughable argument.
How is it laughable? Here we have a common problem, solved by a ten year old standard, and the solution is to ignore it because one compiler doesn't implement it? If it was some other compiler you wouldn't be making the same comment.
The entire problem here is that you're taking things that are for internal use and exposing them to the user
For Allegro 5 that's delibrate as the types are part of the API (as in, we document functions to accept and return values of those types).
I forgot whether they are considered part of the Allegro 4 API.
However, in Allegro 5, we are not using the types are much as we might have so in this case we could probably use purpose-specific types for each case that needs fixed width types.
The same problem occurs for bool, possibly to a lesser extent because C++ has bool.
I like Matthew Leverton's solution, just wrap the necessary emulation headers with that macro and let people who use sub-standard compilers define the macro. Naturally, it should be documented. Or perhaps just let people know the name of the header guard macro for those files (I assume defining it would have the same effect).
Yes, me too. I just remembered that an important use of fixed width types is with al_lock_bitmap/region.
Here we have a common problem, solved by a ten year old standard, and the solution is to ignore it because one compiler doesn't implement it? If it was some other compiler you wouldn't be making the same comment.
That quite frankly is a load of bull. Most libs but Allegro in particular expend a lot of effort to maintain support for antiquated compilers and platforms that pretty much no one in their right mind is going to use today. But when we start talking about 30 second fix for one of your most popular platforms, the response is "screw em"? Yeah, no ulterior motives involved there.
Besides, your argument is moot. A quick glance at the Allegro platform headers shows that at least 4 of the supported compilers do not have support for C99 int types.
Look, the devs for allegro can do as they damn well please. Especially with Allegro 5. Its a new lib, and has no need to support broken C compilers. It works most of the time. If it breaks in some minority of strange cases, thats none of Allegro 5's business.
A quick glance at the Allegro platform headers shows that at least 4 of the supported compilers do not have support for C99 int types.
The actual list of fully SUPPORTED compilers is GCC, GCC, and um, GCC. The rest have quirks that we can't properly support. Allegro can try and work around them, but thats about it.