• Re: Default signedness of 'plain' char.

    From Johann 'Myrkraverk' Oskarsson@johann@myrkraverk.invalid to comp.lang.c,comp.sys.acorn.misc on Mon Aug 3 23:14:53 2026
    From Newsgroup: comp.sys.acorn.misc

    On 03/08/2026 9:47 AM, Kenny McCormack wrote:
    In article <PeMbS.103022$aXr.22087@fx18.ams4>,
    Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> wrote:
    ...
    And why did acc define it signed in the first place? Maybe the CPU only
    had signed bytes, or they were faster than unsigned? I wouldn't know as
    this is a made up example.

    Thank you for your response. I hope to see more responses on this thread.

    But, just out of curiosity, why do you way that "this is a made up example" ? To what are you referring and why do you think it was "made up" ?


    Because I did not bother to dig up my RISC OS computer, and see what
    that C compiler did about the signedness of chars.

    It's a high chance that GCC, when ported to ARM for the first time,
    was compatible with whatever C compiler the original /Acorn/ team
    used, or made.

    I believe I have a continuation of that C compiler on my RISC OS
    machine. So assuming it still works, I can boot it up, and check
    what it does.

    That said, I'm in no hurry, and I'm not sure it still works. It's
    a /Pinebook/ that boots into RISC OS 5.

    Then, we should keep in mind that the /Acorn/ team was used to code
    in assembly. I believe most of RISC OS is coded in assembly, and
    their original C compiler was -- and had to be -- compatible with
    whatever /application binary interface/ they were used to in that
    assembly code.

    So, that's the reason I believe default ARM char is unsigned. I'm
    sure other regulars will be extremely happy to correct me, so let
    them. They enjoy that sport.

    I'm also adding comp.sys.acorn.misc, so the regulars there have a
    chance at correcting this historical tidbit. We'll leave alt.folk- lore.computers alone for now.
    --
    Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
    I'm not from the Internet, I just work there. | via Easynews.com
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Theo@theom+news@chiark.greenend.org.uk to comp.lang.c,comp.sys.acorn.misc on Tue Aug 4 13:13:22 2026
    From Newsgroup: comp.sys.acorn.misc

    In comp.sys.acorn.misc Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> wrote:
    On 03/08/2026 9:47 AM, Kenny McCormack wrote:
    In article <PeMbS.103022$aXr.22087@fx18.ams4>,
    Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> wrote:
    ...
    And why did acc define it signed in the first place? Maybe the CPU only >> had signed bytes, or they were faster than unsigned? I wouldn't know as >> this is a made up example.

    Thank you for your response. I hope to see more responses on this thread.

    But, just out of curiosity, why do you way that "this is a made up example" ?
    To what are you referring and why do you think it was "made up" ?


    Because I did not bother to dig up my RISC OS computer, and see what
    that C compiler did about the signedness of chars.

    It's a high chance that GCC, when ported to ARM for the first time,
    was compatible with whatever C compiler the original /Acorn/ team
    used, or made.

    I believe I have a continuation of that C compiler on my RISC OS
    machine. So assuming it still works, I can boot it up, and check
    what it does.

    I don't have Norcroft C handy to check, but I expect chars are also
    unsigned.

    I wasn't there at the time, but I can make an informed guess as to why. I think it was Steve Furber who famously said that Acorn gave them two unique things when designing the original ARM1: no people and no money. That meant that everything had to be incredibly simple, because they didn't have transistors for anything else.

    That's why the 32 bit ISA has the instruction:
    LDR Rd,[Ra, #n]
    for a 32 bit load, and
    LDRB Rd,[Ra, #n]
    for an 8 bit load.

    Internally, the 8 bit load is just a 4-to-1 mux x 8 bits of the 32 bit
    version. There was no sign extension logic on that datapath (would have
    cost transistors and reduced clock speed), so the read value has zeros in
    the upper 24 bits.

    Also, in that vein, you can easily merge four 8 bit values in registers into a 32-bit word:
    ORR Rd,Rs0,Rs1,LSL#8
    ORR Rd, Rd,Rs2,LSL#16
    ORR Rd, Rd,Rs3,LSL#24

    which sign extension would mess up (you'd have to mask off the sign bits first).

    With that, it's natural for chars to be unsigned. It enables a lot of the
    bit- and byte-twiddling that the A32 instruction set is good at.

    Then, we should keep in mind that the /Acorn/ team was used to code
    in assembly. I believe most of RISC OS is coded in assembly, and
    their original C compiler was -- and had to be -- compatible with
    whatever /application binary interface/ they were used to in that
    assembly code.

    Assembly was popular because A32 assembly is nice to write. Acorn had C and Modula2 compilers from early on (~1985-6), but as an outside developer they cost a couple of hundred pounds (in 1980s money) while an assembler was included in BBC BASIC V in ROM. So there was a natural bias towards
    assembly and BASIC (which works much like raw assembly; no linker)
    programming for non-professional developers. In BBC BASIC bytes are
    unsigned.

    The OS interfaces (SWIs, like Unix syscalls but much broader and extensible) were defined for assembly-first, with shims for calling from C (primarily to force register allocation to match what the SWI wanted; SWIs typically use 8 registers for arguments while C only uses 4 plus the stack). This interface doesn't document explicit types as everything is just a 32 bit word
    (although they can be retrofitted, eg via OSLib) but in practice most values are either 32 bit signed/unsigned or 8 bit unsigned (eg in structs).

    At the time Acorn had two assemblers: AAsm, which only generated standalone assembly output, and ObjAsm which played nicely with the C Linker. So there was indeed a whole other world which was assembly-only and didn't need to
    worry about C. When you were using C, object files were in the Acorn Object Format (AOF) and used the Arm Procedure Calling Standard (APCS-R for RISC
    OS with 26-bit PC; APCS-A was an earlier version for Arthur).

    Nick Burrett did most of the early porting work on GCC for RISC OS circa
    1991; since the whole Acorn world was using AOF and APCS-R, in order to be cross-compatible with libraries that was what GCC had to generate. When upstream GCC moved on to ELF, for a long time we had to maintain AOF output
    to keep compatibility (RISC OS GCC 3.4.6 [I think] is the last AOF
    version; GCC 4 uses ELF).

    So, that's the reason I believe default ARM char is unsigned. I'm
    sure other regulars will be extremely happy to correct me, so let
    them. They enjoy that sport.

    So TL;DR, as I see it:

    - the architecture made its 8 bit datatype zero-extended because it
    was the cheapest thing to do in silicon
    - assembly programmers used unsigned 8-bit datatypes because that's what the architecture made easy and cheap, but also because it was the most natural
    - BBC BASIC on the 6502 had unsigned bytes and those carried over to ARM BBC BASIC
    - Acorn C followed their lead
    - GCC naturally had to follow what Acorn C did
    - in all cases it was the best fit for the architecture anyway

    Theo
    --- Synchronet 3.22a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.lang.c,comp.sys.acorn.misc on Wed Aug 5 07:30:09 2026
    From Newsgroup: comp.sys.acorn.misc

    On 04 Aug 2026 13:13:22 +0100 (BST), Theo wrote:

    Also, in that vein, you can easily merge four 8 bit values in
    registers into a 32-bit word:

    ORR Rd,Rs0,Rs1,LSL#8
    ORR Rd, Rd,Rs2,LSL#16
    ORR Rd, Rd,Rs3,LSL#24

    which sign extension would mess up (you'd have to mask off the sign
    bits first).

    ThatrCOs what happens in general: any kind of bit-twiddling is usually
    much easier with unsigned rather than signed integer types (of
    whatever size).

    I once had to do some inter-process communication between a clientrCOs
    online shop system and the payment processor. The code library they
    provided was written in Java, so I wrote a wrapper app around that to communicate with the main shop system (which I had written in C++).

    (Seasoned Java programmers can probably already guess where this story
    is going ...)

    About once a week or so, a payment would fail to go through. Took me
    quite a few examinations of debug messages before I realized that,
    because Java only has signed integers and no unsigned, I was sometimes computing a length field incorrectly due to sign extension.

    Put in the necessary masking calls, and all was hunky-dory after that.
    --- Synchronet 3.22a-Linux NewsLink 1.2