8

Is char signed or unsigned by default on iOS?

(I thought this would've been a well answered question, but oddly google turned up nothing at all useful!)

JosephH
  • 37,173
  • 19
  • 130
  • 154

2 Answers2

14

In most cases, char is unsigned on ARM (for performance reasons) and signed on other platforms.

iOS differs from the normal convention for ARM, and char is signed by default. (In particular this differs from Android, where code compiled in the ndk defaults to unsigned char.)

This can be changed in xcode, there is a 'char' Type is unsigned option (which defaults to off). If this is changed to "yes", xcode will pass -funsigned-char to llvm. (Checked on xcode 5.0.2)

The reason why iOS differs is mentioned in iOS ABI Function Call Guide: ARM64 Function Calling Conventions, which says simply:

In iOS, as with other Darwin platforms, both char and wchar_t are signed types.

Community
  • 1
  • 1
JosephH
  • 37,173
  • 19
  • 130
  • 154
  • 1
    I didn't know ARM toolchains defaulted to `unsigned char`! :o Thanks for sharing this! –  Dec 13 '13 at 21:30
  • 1
    The ARM EABI defines `char` as being unsigned; this is why normal toolchains do it. EABI does a lot of stupid things, but it's the "standard" for ARM, and the mix of incompatible ABIs each with their own broken quirks that existed before EABI came around was probably worse than the EABI we're stuck with now. – R.. GitHub STOP HELPING ICE Dec 13 '13 at 21:53
  • 3
    The main reason `char` is unsigned in EABI is an unsigned `char` type allows faster code on ARM as ARM load and store instructions of bytes work with unsigned values (no sign extension). – ouah Dec 13 '13 at 22:04
  • 2
    @ouah Honestly, I find it more logical to default to an unsigned char, since `char` is often used for binary byte-wise operations and for representing characters in a string. –  Dec 13 '13 at 22:21
  • It used to be unsigned by default on ARM, but it was changed to signed some time ago, I think it's from ARMv7 Cortex. – Jake 'Alquimista' LEE Dec 14 '13 at 03:01
  • 1
    @R.. Except for the 8 byte stack alignment requirement and unsigned char by default, I don't see much wrong with the ABI. – sgupta Dec 27 '13 at 01:39
  • 1
    @ouah No, char is unsigned in EABI because earlier ARM cpu(s) didn't have ldr[s](h/b) which required the CPU to first load the value as unsigned and then sign extend by rotating them. Ever since the introduction of ldr[s](b/h), Performance is same for signed and unsigned character loads/stores. – sgupta Dec 27 '13 at 01:42
  • @Jake'Alquimista'LEE It is still unsigned in the standard ARM EABI, iOS chose to deviate from it. Also iirc, R9 is a volatile register accross proceedures in iOS while it must be preserved according to ARMEABI. – sgupta Dec 27 '13 at 01:45
  • @user1075375: The ABI has a lot of silly requirements like the existence of various `__aeabi_*` symbols. Some are for compiler-runtime stuff like long division, where it would be just as good for GCC to use the same symbol names it uses on other platforms; the worst that would happen when mixing code from different compilers is that you might end up with multiple copies of such code. Other `__aeabi_*` symbols are much stupider, such as the duplicate of `__cxa_atexit` with the argument order reversed and other useless stuff... – R.. GitHub STOP HELPING ICE Dec 27 '13 at 02:00
  • @user1075375: I'm skeptical of your claims about lack of `ldrsb` on old ARMs being the reason for unsigned `char`. EABI requires at least armv4t, and as far as I can tell, `ldrsb` was added well before then. – R.. GitHub STOP HELPING ICE Dec 27 '13 at 02:04
  • @R.. Where exactly does the EABI explicitly mention the requirement of ARMv4T ? – sgupta Dec 27 '13 at 02:25
  • @R.. Why would you worry about the __aeabi_* symbols unless you're only working with bare metal and even then, with -mno-builtin + a simple implementation is all you need which are available all over the web. – sgupta Dec 27 '13 at 02:30
  • @user1075375: The EABI requires procedures to support thumb interworking (calling to, and returning from calls made from, thumb procedures, and vice versa) and specifies `bx` as the return mechanism. `bx` is not available pre-armv4t. It's possible to make a return sequence that works on all ARMs (`tst lr,#1 ; moveq pc,lr ; bx lr`) but sadly no compilers do this and the EABI does not require them to do so. – R.. GitHub STOP HELPING ICE Dec 27 '13 at 03:16
  • @R.. The debian wiki page which mentions that workaround also mentions several other software based workarounds. Infact, in an all ARM compiled system, the presensce of interworking doesn't make any difference to the EABI. ARM EABI based binaries without thumb code can thus be used on ARMv3 systems and with thumb code (+ performance hit). – sgupta Dec 27 '13 at 13:00
  • @user1075375 I read that in one of ARM's PDFs. I think it was bundled in the DS-5 bundled one. – Jake 'Alquimista' LEE Dec 28 '13 at 07:42
1

why didnt you just try it?

char x,y;

x=y=0x7F;
x++;
if(x>y) unsigned else signed...
old_timer
  • 69,149
  • 8
  • 89
  • 168