Why use TBool vs. bool?
| Fri, 2007-01-26 19:51 | |
|
I am curious why Symbian users should use TBool instead of the standard C type bool. I did an experiment where I compiled some test code that has method using bool and one using TBool. The results were different.
Code: bool UseCBool() { bool one = true; bool two = false; if (one || two) return one; else return two; } // Disassembly ........ ; bool __cdecl UseCBool(void) public ?UseCBool@@YA_NXZ ?UseCBool@@YA_NXZ proc near ; CODE XREF: TestBools(void)+6p one = byte ptr -2 two = byte ptr -1 push ebp mov ebp, esp push ecx mov [ebp+one], 1 mov [ebp+two], 0 movzx eax, [ebp+one] test eax, eax jnz short loc_C0 movzx ecx, [ebp+two] test ecx, ecx jz short loc_C5 loc_C0: ; CODE XREF: UseCBool(void)+12j mov al, [ebp+one] jmp short loc_C8 ; --------------------------------------------------------------------------- loc_C5: ; CODE XREF: UseCBool(void)+1Aj mov al, [ebp+two] loc_C8: ; CODE XREF: UseCBool(void)+1Fj mov esp, ebp pop ebp retn ?UseCBool@@YA_NXZ endp Now here is the same code using TBool: Code: TBool UseSymbianBool() { TBool one = ETrue; TBool two = EFalse; if (one || two) return one; else return two; } // disassembly ...... ; int __cdecl UseSymbianBool(void) public ?UseSymbianBool@@YAHXZ ?UseSymbianBool@@YAHXZ proc near ; CODE XREF: TestBools(void)+Ep var_8 = dword ptr -8 var_4 = dword ptr -4 push ebp mov ebp, esp sub esp, 8 mov [ebp+var_8], 1 mov [ebp+var_4], 0 cmp [ebp+var_8], 0 jnz short loc_F4 cmp [ebp+var_4], 0 jz short loc_F9 loc_F4: ; CODE XREF: UseSymbianBool(void)+18j mov eax, [ebp+var_8] jmp short loc_FC ; --------------------------------------------------------------------------- loc_F9: ; CODE XREF: UseSymbianBool(void)+1Ej mov eax, [ebp+var_4] loc_FC: ; CODE XREF: UseSymbianBool(void)+23j mov esp, ebp pop ebp retn ?UseSymbianBool@@YAHXZ endp I'll point out a few differences: 1. The "bool" has size 1 vs. TBool's size 4. 2. The check for true/false is done with cmp with TBool, but with test with bool. And also, I checked the ARM code too. Here are the two same functions disassembled: Code: ; UseCBool(bool,bool) EXPORT UseCBool__Fbb UseCBool__Fbb CMP R0, #0 BXNE LR CMP R1, #0 MOVEQ R0, R1 BX LR ; End of function UseCBool(bool,bool) ; UseSymbianBool(int,int) EXPORT UseSymbianBool__Fii UseSymbianBool__Fii MOV R3, R0 MOV R2, R1 CMP R1, #0 CMPEQ R0, #0 MOVEQ R0, R2 MOVNE R0, R3 BX LR ; End of function UseSymbianBool(int,int) Notice that the TBool function is longer than the bool function! (I believe it's longer because the compiler couldn't optimize the ints as well as the bools; ints can be 0-0xFFFFFFFF, while bools can only be true/false, so it had to create 2 additional storage registers, R2 and R3 for the ints) These results leave me to believe that I should be using bool instead of TBool. The compiler can optimize it better, and it's smaller, and in most cases can probably make it faster since it isn't required to be a 4-byte int as opposed to a undefined-byte-size bool. Can anyone give me a good argument to why I should be using TBool? -euroq |
|






Forum posts: 723
- TBool starts with a 'T', whereas 'bool' doesn't ==> remember TAny and coding convention!
- Maybe 'bool' keyword was not available when Symbian basic datatypes were worked out?
I don't think the reason is more complex!
Tote
Gabor Torok
Software architect, Agil Eight (http://www.agileight.com/)
Blog: http://mobile-thoughts.blogspot.com/
Forum posts: 110
It's for historical reasons really, early compilers didn't have a bool type. I'm not sure why Symbian haven't changed it: probably because "they say that if it isn't broke don't fix it"
More to the point your analysis is correct: that the compiler should be able to optimise better if it knows a variable can only have true or false values.
I think it's probably possible to just hack the header (e32std.h ?)Â so that TBool becomes a bool. You might also be able to fix the annoying warnings that GCCE generates about ETrue and EFalse being different enums.
Just checked the header file (e32def.h):
/**
@publishedAll
@released
Boolean type which takes the value either ETrue or EFalse.
Although only a single bit would theoretically be necessary to represent a
Boolean, a machine word is used instead, so that these quantities can be easily
passed. Also, TBool must map onto int because of C++'s interpretation of
operands in conditional expressions.
On implementations of Symbian OS in which the compiler supports the ANSI-recommended
bool type, TBool will be typedef'ed to bool instead of int.
*/
typedef int TBool;
I guess they forgot to change itÂ
Forum posts: 149
Boolean, a machine word is used instead, so that these quantities can be easily
passed. Also, TBool must map onto int because of C++'s interpretation of
operands in conditional expressions.
One wise thing I learned in school is to never try to outsmart the compiler. The compiler can figure out the best way to pass a bool (if it wants to send the bool as 4 bytes to align it to a machine word, that's fine with me). From now on in, I'm using exclusively bool instead of TBool.
They probably figured this would break backwards compatibility. But with the release of Symbian 3rd Edition, as it is a binary-break release, this would have been a perfect time to change it.
-euroq
Forum posts: 53
I now think to use more of standard c++ on symbian 9. Developement will be easier, and code will bo more portable. I use bool for my staff and TBool only if its needed by some symbian functions....
I also cant figure out why to use TInt instead of int??? This works the same. Only convetion is another...
Wojciech Freliszka
NinthBit
Forum posts: 110
Yes, it would and they should have done it. But inevitably they had to find the right balance between changing things and maintaining backwards compatibility. It probably wasn't something that was considered very important (and in the big scheme of things it isn't). The key changes were the new kernel, platform security, and the change over to use a completely new tool chain (GCCE / ARM compilers). Those were the things that really mattered.
What's most annoying about them not changing this is that GCCE generates warnings every time you use ETrue and EFalse in the same expression (e.g bigY = (y>2) ? ETrue : EFalse). Of course the people at Symbian wouldn't have noticed this as they don't use GCCE!
For me this is all about good object orientated design. That everything in your code has a clear purpose: any class of objects beginning with T are essentially passive blocks of data. Any class beginning with R represent a handle to a resource of some kind (which you "borrow" from the system). Any objects of C classes are actors within your program: they are things that "do stuff".
In terms of making code more portable my advice is to always try to seperate your code into the components that have to be portable and those that have to interface with the OS. In the portable parts you may as well use bools and standard C++ exceptions (these work on Symbian now, or at least I think they do. Can somebody confirm this?) but in the OS specific stuff I would continue to follow the Symbian coding guidelines.
Forum posts: 3
Bit like asking why use TInt instead of default compiler option for ints. Good practice + any complier differences and/or enchancements can be taken advantage of as required by a single change of the data type definition.
Its no accident that practically all platforms choose to define their own data type sets...
Forum posts: 9
I now think to use more of standard c++ on symbian 9. Developement will be easier, and code will bo more portable.
But if "Leaves" were changed to C++ exceptions, THAT would be one and only MAJOR development speedup.
Forum posts: 149
I did this on the only two that matter: the emulator and the device. Also, I can positively say that the compiler is always going to be able to optimize a native bool type better than TBool. The two examples show this. (However, I'm not saying that every use of a bool vs. int will be better optimized... obviously some code will always look the same, whether it's an int or a bool).
Yes I know about machine word alignment. And once again, the compiler will handle this. It will align them in structs, it will also pass bools in whatever method is best, and create optimized conditionals with bools better than ints. Point is, you will (well, can in most instances) save something by switching from ints to bools.
Its no accident that practically all platforms choose to define their own data type sets...
Agreed. C's history has always been all about making the code work best for the platform it's compiled for, not for all platforms. Which is why we have abstract data primitives (int, long), so that it maps to the machine the best. So if you're always using primitive data types, and expecting them to be a certain way cross-platform (i.e. 32 bits), you're going to run into trouble. C99 now has some new primitive types such as Int8, Int16, Int32, etc.
Still, the point is that TBools aren't as optimizable as bools.
Forum posts: 149
That would be a disaster! If you changed the headers of the SDK, every SDK method which uses a TBool would be compiled wrong in your code. The worst thing is, probably a lot of your program would work and then all of a sudden crash.
But it sure would be awesome to get rid of the ETrue/EFalse warnings, without having to cast every single comparison!
By the way, how do you know that the people at Symbian don't use GCCE, what do they use instead?
Forum posts: 110
Good to see you spotted that
I suspect that your app simply wouldn't link. The linker would be looking for Symbian OS functions using bools but it would only find ones that used ints!
Anyway it would work fine if it was Symbian doing the hacking
My guess is all they have to do is
typedef bool TBool;
#define ETrue true
#define EFalse false
ARM don't just make the processors they also provide a compiler for them:
http://www.arm.com/products/DevTools/RealViewDEVELOP_Family.html
Forum posts: 149
My guess is all they have to do is
typedef bool TBool;
#define ETrue true
#define EFalse false
Unfortunately, Symbian has just promised that Symbian 3rd Edition (OS 9) is going to be binary compatible from now on. Which means they (or we) might have just lost the last opportunity to fix these problems that depend on compatibility with older editions.
-euroq