Page 1 of 1
About Android NDK and GCC problem
Posted: Sat Dec 13, 2014 9:59 pm
by Boolean
Hello everyone.
I am porting my emulator to Android Platform.
At this point, I meet a strange thing.
See below.
Code: Select all
// C/C++ code, modified from 6502 relative addressing mode of my emulator
char Buf[1025];
int Result;
unsigned char c = 0xFF;
Result = 0xC001 + (char) c;
sprintf(Buf, "c = %X, result = C001 + (char)c = %X\nCompiled by %d.%d.%d",
c, Result, __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
cout<<Buf<<endl;
MinGW outputs
--------------------------------------------------
c = FF, result = C001 + (char)c = C000
Compiled by 4.8.1
--------------------------------------------------
Android outputs
<see attachment>
The result should be "C000", but Android's output is error.
How to deal with it?
Re: About Android NDK and GCC problem
Posted: Sat Dec 13, 2014 10:08 pm
by lidnariq
Boolean wrote:Code: Select all
unsigned char c = 0xFF;
Result = 0xC001 + (char) c;
MinGW's GCC is actually the wrong one here.
C's type promotions say that addition always promotes smaller types to (at least)
int, so your cast here is ignored.
To get the wrapping you want, I think you'll have to do this explicitly (e.g. (0xC001 &~0xFF) | ((0xC001 + c)&0xFF)
Re: About Android NDK and GCC problem
Posted: Sun Dec 14, 2014 2:57 am
by thefox
Android NDK defaults char to unsigned, so both are correct.
Re: About Android NDK and GCC problem
Posted: Sun Dec 14, 2014 3:59 am
by Sik
Also the reason why char isn't the same type as either its signed or unsigned counterpart, the type of char is completely dependent on the implementation. This doesn't happen with any of the other basic types. Surprised that there's a modern platform that makes char unsigned by default, though.
There's also the fact that a sign conversion that results in overflow (i.e. the value wouldn't fit in a signed integer of that size) is undefined, so if the compiler wanted it could skip the conversion, or skip the calculation, or make the program crash, or do whatever it wants, really.
Re: About Android NDK and GCC problem
Posted: Sun Dec 14, 2014 6:23 am
by Joe
If char is a signed type, this conversion is implementation defined behavior. Different compilers are free to produce different results, but within the same compiler the result will be consistent.
If char is an unsigned type, the conversion does nothing and the result is 0xC100.
Both compilers are correct.
Re: About Android NDK and GCC problem
Posted: Tue Dec 16, 2014 6:54 pm
by Boolean
lidnariq wrote:
To get the wrapping you want, I think you'll have to do this explicitly (e.g. (0xC001 &~0xFF) | ((0xC001 + c)&0xFF)
It is OK.
thefox wrote:Android NDK defaults char to unsigned, so both are correct.
Sik wrote:...
Joe wrote:...
You three are right.
char equals
unsigned char(arm-linux-gcc)
char equals signed char(gcc)
char equals signed char(vc)
Thank you all. I find an evidence.
n3337.pdf (Working Draft, Standard for Programming Language C++) Page 71 wrote:
In any particular implementation, a plain char object can take on
either the same values as a signed char or an unsigned char;which
one is implementation-defined
So when you use char type, you'd better add signed/unsigned keyword before char.
Instead of
Result = 0xC001 + (char) c;, I'll use
Result = 0xC001 + (signed char) c;.
Re: About Android NDK and GCC problem
Posted: Wed Dec 17, 2014 10:36 am
by Joe
Boolean wrote:Instead of Result = 0xC001 + (char) c;, I'll use Result = 0xC001 + (signed char) c;.
The conversion from unsigned char to signed char is still implementation-defined behavior. This will probably be fine on all of your target platforms, but be aware there are platforms where this will not do what you expect.
Re: About Android NDK and GCC problem
Posted: Wed Dec 17, 2014 11:14 am
by tepples
Joe wrote:The conversion from unsigned char to signed char is still implementation-defined behavior.
Based on differences in
CHAR_BIT or on something else?
Re: About Android NDK and GCC problem
Posted: Wed Dec 17, 2014 2:12 pm
by Joe
If CHAR_BIT is greater than 8, the conversion will not change the value, and the result will again be 0xC100.
If CHAR_BIT is equal to 8, the result of the conversion is still not guaranteed to be -1 as expected:
When a value with integer type is converted to another integer type other than _Bool, if [...] the new type is signed and the value cannot be represented in it[,] either the result is implementation-defined or an implementation-defined signal is raised.
The vast majority of C compilers define CHAR_BIT as 8, and define unsigned to signed conversions as a simple reinterpretation of the bit pattern as a two's complement signed number. However, neither of these properties are guaranteed by the C standard.
Re: About Android NDK and GCC problem
Posted: Tue Dec 23, 2014 7:29 pm
by Boolean
When you two talk about CHAR_BIT macro, I realize I must search some related info.
After some adjustments,
1. I use <stddef.h> to typedef some types.
typedef uint8_t byte;
typedef int8_t int8; // relative addressing mode uses it
typedef int64_t int64;
2. I use <limits.h> to validate normal int type must be great or equal 32 bits.
What types I mainly used in my project are byte, int8, int, int64 and some custom types(i.e. struct, class, enum).
I think it should be OK.
Re: About Android NDK and GCC problem
Posted: Tue Dec 23, 2014 8:29 pm
by rockcarry
How about your porting on android platform, does it work now.
Re: About Android NDK and GCC problem
Posted: Thu Dec 25, 2014 6:48 pm
by Boolean
rockcarry wrote:How about your porting on android platform, does it work now.
Now, It can output video.
Thread [color=#80FF00]main[/color] loop wrote:
Process Activity UI messages and insert menu requests to menu queue.(Java Code)
Thread [color=#80FF00]Thread-FC87[/color] loop wrote:
Emulation: A frame picture's pure emulation time is approximately 20 milliseconds.(C/C++ Native Code)
Output: A frame picture's output(by SurfaceView) time is approximately 4 milliseconds.(Java Code)
UI Response: Remove a menu request from menu queue(Java Code) and execute its real function.(C/C++ Native Code)
I consider to create a thread to process video output.
Audio output and User input are not implemented by me.
I have a question about User input.
For Win32, When a game write 1 then 0 to $4016, I must call GetKeyState(Win32 API) to acquire User input info.
But for Android, I don't know whether User touch screen or not via C/C++ Native Code.