Should embedded systems compilers be trusted

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?ISO-8859-1?Q?Tom=E1s_=D3_h=C9ilidhe?=

    Should embedded systems compilers be trusted


    There are a few guarantees I exploit in the C Standard. For instance,
    I might write

    (unsigned)-1

    to get the maximum value for an unsigned integer.

    Also, I might rely on things such as:

    memset(data,-1,sizeof data)

    to set all bits in a chunk of memory to 1.

    I'm using an embedded systems compiler now though and I'm hesitant to
    trust it with things like this. I've already come across the following
    quirks:

    1) You can't define a variable as const unless it can be put in the
    chip's ROM.
    2) There's no stack used by default; you must define a function as
    "reentrant" if you want a stack.

    To the people here who have experience with embedded systems C
    compilers, how do you feel about trusting its C compliance? Some
    issues I'd be concerned about are:

    1) int being at least 16-Bit
    2) long being at least 32-Bit
    3) Compliant conversion between signed and unsigned types

    I'm using the PIC C compiler to program the PIC16F684 chip.
  • Bill Leary

    #2
    Re: Should embedded systems compilers be trusted


    "Tomás Ó hÉilidhe" <toe@lavabit.co mwrote in message
    news:02ef9298-fa3e-42b6-8dbd-dc8ebd926cd7@26 g2000hsk.google groups.com...
    >
    There are a few guarantees I exploit in the C Standard. For instance,
    I might write
    >
    (unsigned)-1
    >
    to get the maximum value for an unsigned integer.
    >
    Also, I might rely on things such as:
    >
    memset(data,-1,sizeof data)
    >
    to set all bits in a chunk of memory to 1.
    >
    I'm using an embedded systems compiler now though and I'm hesitant to
    trust it with things like this. I've already come across the following
    quirks:
    >
    1) You can't define a variable as const unless it can be put in the
    chip's ROM.
    2) There's no stack used by default; you must define a function as
    "reentrant" if you want a stack.
    >
    To the people here who have experience with embedded systems C
    compilers, how do you feel about trusting its C compliance? Some
    issues I'd be concerned about are:
    >
    1) int being at least 16-Bit
    2) long being at least 32-Bit
    3) Compliant conversion between signed and unsigned types
    >
    I'm using the PIC C compiler to program the PIC16F684 chip.
    In most embedded compilers I've used, they've had a section either in the
    on-line help for the package or in the manual where they summarized the
    standard they were targeting (such as C89) and what their variations from
    that were. Items such as the storage location of consts and stack behavior
    are pretty common for those I've used. Some other compilers, on the other
    hand, have had a comment somewhere that they were "based on C" or "having
    roots in C" or some such. In these cases all bets were pretty much off.

    For the items you mention (size of ints/longs, conversion) the packages
    often supply definitions (i16, int32, uint8) which you'd use instead of the
    standard names to ensure that the sizes you've coded for are kept and are
    quite explicit on how conversions are done. Even with these, I usually put
    a bit of code as early in the system as I can that verifies the coding
    assumptions about sizes, conversions, stack operation, initialization and so
    on and stops the machine with some error indication if they're wrong. These
    tests should really only ever trigger in the development environment, and
    you might figure they'd never really happen, but I have had them go off a
    couple of times (usually right after a development package upgrade) and
    they've saved me a lot of grief tracking down what would have been subtle
    bugs. In one case one of them triggered when the part was changed due to
    the way it handled I/O 16 bit quantities. The earlier part only had 8 bit
    I/O, the new one had 8 and 16, but the previous engineer had assumed he
    could throw 16 bit data and a 8 bit port and it would truncate the bits for
    him. Well, it did, but the new part worked it differently. When code space
    was limited, I'd put these tests in some #define for debug or development.

    You might try comp.arch.embed ded for this question. From what I've seen
    over the years, this group pretty much assumes you're using a compliant
    compiler.

    - Bill

    Comment

    • Barry Schwarz

      #3
      Re: Should embedded systems compilers be trusted

      On Sun, 20 Apr 2008 04:18:56 -0700 (PDT), Tomás Ó hÉilidhe
      <toe@lavabit.co mwrote:
      >
      >There are a few guarantees I exploit in the C Standard. For instance,
      >I might write
      >
      (unsigned)-1
      >
      >to get the maximum value for an unsigned integer.
      The standard guarantees that values for unsigned integers behave
      nicely when they wrap in either direction. However, your code will
      not work for an integer type wider than int. For C89 you probably
      need (unsigned long) -1L and for C99 (unsigned long long) -1LL.
      >
      >Also, I might rely on things such as:
      >
      memset(data,-1,sizeof data)
      >
      >to set all bits in a chunk of memory to 1.
      >
      This only works on 2s-complement systems.
      >I'm using an embedded systems compiler now though and I'm hesitant to
      >trust it with things like this. I've already come across the following
      >quirks:
      >
      >1) You can't define a variable as const unless it can be put in the
      >chip's ROM.
      >2) There's no stack used by default; you must define a function as
      >"reentrant" if you want a stack.
      >
      >To the people here who have experience with embedded systems C
      >compilers, how do you feel about trusting its C compliance? Some
      >issues I'd be concerned about are:
      >
      >1) int being at least 16-Bit
      >2) long being at least 32-Bit
      >3) Compliant conversion between signed and unsigned types
      >
      >I'm using the PIC C compiler to program the PIC16F684 chip.

      Remove del for email

      Comment

      • Jack Klein

        #4
        Re: Should embedded systems compilers be trusted

        On Sun, 20 Apr 2008 04:18:56 -0700 (PDT), Tomás Ó hÉilidhe
        <toe@lavabit.co mwrote in comp.lang.c:
        >
        There are a few guarantees I exploit in the C Standard. For instance,
        I might write
        >
        (unsigned)-1
        >
        to get the maximum value for an unsigned integer.
        Right, or for any other unsigned type, (unsigned type)-1. Or if you
        are assigning or initializing any unsigned integer type, just plain
        old ordinary -1.
        Also, I might rely on things such as:
        >
        memset(data,-1,sizeof data)
        >
        to set all bits in a chunk of memory to 1.
        Really? I never have, can't think of anybody who has. Do you really
        do this? Why? I've never had a need for a block of memory with all
        bits 1. Of course, if the array is of one of the unsigned integer
        types, you're safe unless these types contain padding, and I've never
        heard of that it anything used for embedded wok.
        I'm using an embedded systems compiler now though and I'm hesitant to
        trust it with things like this. I've already come across the following
        quirks:
        >
        1) You can't define a variable as const unless it can be put in the
        chip's ROM.
        This is not a quirk. C does not define things like "ROM" or "RAM".
        You told the compiler that you wanted to define an object that would
        not be changed. The compiler obligingly put it into memory where it
        could not be changed. What's your objection?
        2) There's no stack used by default; you must define a function as
        "reentrant" if you want a stack.
        This one is a true gotcha on some of the small, antique 8-bitters.
        They have severe hardware limitations on the size of the stack. I
        don't (won't) use PIC, the architecture is too bizarre without
        sufficient reason, but 8051 derivatives have the same issue.
        To the people here who have experience with embedded systems C
        compilers, how do you feel about trusting its C compliance? Some
        issues I'd be concerned about are:
        Frankly, you are asking the wrong question. And even if it is the
        right question, you should probably be asking it on comp.arch.embed ded
        rather than here.

        "Trust" is not the right word. Most embedded compilers, especially
        those which call themselves "ANSI C" compiler (which is all of them),
        provide a subset of the C language and therefore aren't really
        conforming at all.
        1) int being at least 16-Bit
        ISTM one compiler, I think for much older PICs which had even more
        limitations that had a 12-bit int.
        2) long being at least 32-Bit
        I also seem to remember one embedded compiler that had used something
        less than 32 bits for long.
        3) Compliant conversion between signed and unsigned types
        >
        I'm using the PIC C compiler to program the PIC16F684 chip.
        As others have pointed out, just about every compiler comes with
        documentation, either hard copy or electronic. The documentation will
        tell you what the compiler does in these, and other cases.

        But I still think "trust" is the wrong concept. C was designed (and
        defined) as an efficient systems computing language for general
        computing. Many of its features, and its efficiency, make it
        extremely useful for embedded systems. But many embedded systems have
        hardware architectures that make a full implementation of C either
        completely impossible or incredibly impractical.

        If you are using a new compiler for a new architecture, familiarize
        yourself with its documentation, especially in areas of the language
        that are "implementa tion-defined", and areas where it documents
        limitations or omissions in conforming to the standard.

        If anything is still questionable after reading and understanding the
        documentation, contact the vendor's tech support, if such exists. Or
        even better, write and build code. See what it does by examining the
        object code generated, or by testing the code.

        The concept of "trust" for an embedded compiler, in the sense you use
        it here, seems at odds with the kind of due diligence I would expect
        an experienced embedded systems developer to do.

        --
        Jack Klein
        Home: http://JK-Technology.Com
        FAQs for
        comp.lang.c http://c-faq.com/
        comp.lang.c++ http://www.parashift.com/c++-faq-lite/
        alt.comp.lang.l earn.c-c++

        Comment

        • Richard

          #5
          Re: Should embedded systems compilers be trusted

          Jack Klein <jackklein@spam cop.netwrites:
          On Sun, 20 Apr 2008 04:18:56 -0700 (PDT), Tomás Ó hÉilidhe
          <toe@lavabit.co mwrote in comp.lang.c:
          >
          >>
          >There are a few guarantees I exploit in the C Standard. For instance,
          >I might write
          >>
          > (unsigned)-1
          >>
          >to get the maximum value for an unsigned integer.
          >
          Right, or for any other unsigned type, (unsigned type)-1. Or if you
          are assigning or initializing any unsigned integer type, just plain
          old ordinary -1.
          >
          >Also, I might rely on things such as:
          >>
          > memset(data,-1,sizeof data)
          >>
          >to set all bits in a chunk of memory to 1.
          >
          Really? I never have, can't think of anybody who has. Do you really
          do this? Why? I've never had a need for a block of memory with all
          bits 1.
          Which means nothing to those of us who have. And there are/were multiple
          reasons and scenarios for just this. I'm unsure as to why you explain
          what you may or may not have done when the poster is talking about why
          he uses this.

          Comment

          • Robert Gamble

            #6
            Re: Should embedded systems compilers be trusted

            On Apr 20, 2:28 pm, Barry Schwarz <schwa...@dqel. comwrote:
            On Sun, 20 Apr 2008 04:18:56 -0700 (PDT), Tomás Ó hÉilidhe
            >
            <t...@lavabit.c omwrote:
            >
            There are a few guarantees I exploit in the C Standard. For instance,
            I might write
            >
            (unsigned)-1
            >
            to get the maximum value for an unsigned integer.
            >
            The standard guarantees that values for unsigned integers behave
            nicely when they wrap in either direction. However, your code will
            not work for an integer type wider than int. For C89 you probably
            need (unsigned long) -1L and for C99 (unsigned long long) -1LL.
            What makes you think that?

            --
            Robert Gamble

            Comment

            • Peter Nilsson

              #7
              Re: Should embedded systems compilers be trusted

              Tomás Ó hÉilidhe wrote:
              There are a few guarantees I exploit in the C Standard. For instance,
              I might write
              >
              (unsigned)-1
              >
              to get the maximum value for an unsigned integer.
              This is required behaviour for unsigned integer types.
              Also, I might rely on things such as:
              >
              memset(data,-1,sizeof data)
              >
              to set all bits in a chunk of memory to 1.
              That function need not be available on a freestanding implementation.
              If it is available though, the behaviour should work as you describe.
              I'm using an embedded systems compiler now though and I'm
              hesitant to trust it with things like this. I've already come across
              the following quirks:
              >
              1) You can't define a variable as const unless it can be put in the
              chip's ROM.
              2) There's no stack used by default; you must define a function as
              "reentrant" if you want a stack.
              >
              To the people here who have experience with embedded systems C
              compilers, how do you feel about trusting its C compliance? Some
              issues I'd be concerned about are:
              >
              1) int being at least 16-Bit
              2) long being at least 32-Bit
              3) Compliant conversion between signed and unsigned types
              >
              I'm using the PIC C compiler to program the PIC16F684 chip.
              Rather than asking if the code will work on possibly non-conforming
              implementations , wouldn't it be better to get (or build) yourself some
              conformance tests and only use compilers that _are_ conforming?

              If the source is to be compiled by the client, then I suggest you
              charge significant amounts of money for any service contract
              you enter into based on whether they are using a conforming
              compiler or not.

              --
              Peter

              Comment

              • Barry Schwarz

                #8
                Re: Should embedded systems compilers be trusted

                On Sun, 20 Apr 2008 15:21:23 -0700 (PDT), Robert Gamble
                <rgamble99@gmai l.comwrote:
                >On Apr 20, 2:28 pm, Barry Schwarz <schwa...@dqel. comwrote:
                >On Sun, 20 Apr 2008 04:18:56 -0700 (PDT), Tomás Ó hÉilidhe
                >>
                ><t...@lavabit. comwrote:
                >>
                >There are a few guarantees I exploit in the C Standard. For instance,
                >I might write
                >>
                (unsigned)-1
                >>
                >to get the maximum value for an unsigned integer.
                >>
                >The standard guarantees that values for unsigned integers behave
                >nicely when they wrap in either direction. However, your code will
                >not work for an integer type wider than int. For C89 you probably
                >need (unsigned long) -1L and for C99 (unsigned long long) -1LL.
                >
                >What makes you think that?
                For sake of discussion, let us assume a 16 bit int and a 32 bit long
                and the common UINT_MAX and ULONG_MAX for these sizes.

                The statement
                unsigned long x = (unsigned)-1;
                will set x to 65535 (the value of the right hand side) which is
                0x0000ffff, hardly the maximum value for this unsigned long.


                Remove del for email

                Comment

                • Keith Thompson

                  #9
                  Re: Should embedded systems compilers be trusted

                  Jack Klein <jackklein@spam cop.netwrites:
                  On Sun, 20 Apr 2008 04:18:56 -0700 (PDT), Tomás Ó hÉilidhe
                  <toe@lavabit.co mwrote in comp.lang.c:
                  [...]
                  >I'm using an embedded systems compiler now though and I'm hesitant to
                  >trust it with things like this. I've already come across the following
                  >quirks:
                  >>
                  >1) You can't define a variable as const unless it can be put in the
                  >chip's ROM.
                  >
                  This is not a quirk. C does not define things like "ROM" or "RAM".
                  You told the compiler that you wanted to define an object that would
                  not be changed. The compiler obligingly put it into memory where it
                  could not be changed. What's your objection?
                  Suppose I want to define the following (inside a function):

                  const time_t now = time();

                  Or substitute for some other function for time() if it's a
                  freestanding implementation that doesn't support <time.h>.

                  "const" in C means read-only. It sounds like the C-like compiler
                  being described treats "const" as meaning truly constant, i.e.,
                  capable of being evaluated at compile time. If it requires
                  const-qualified objects at block scope to have constant initializers,
                  it's not a conforming C compiler.

                  [...]

                  --
                  Keith Thompson (The_Other_Keit h) <kst-u@mib.org>
                  Nokia
                  "We must do something. This is something. Therefore, we must do this."
                  -- Antony Jay and Jonathan Lynn, "Yes Minister"

                  Comment

                  • Robert Gamble

                    #10
                    Re: Should embedded systems compilers be trusted

                    On Apr 20, 11:59 pm, Barry Schwarz <schwa...@dqel. comwrote:
                    On Sun, 20 Apr 2008 15:21:23 -0700 (PDT), Robert Gamble
                    >
                    >
                    >
                    <rgambl...@gmai l.comwrote:
                    On Apr 20, 2:28 pm, Barry Schwarz <schwa...@dqel. comwrote:
                    On Sun, 20 Apr 2008 04:18:56 -0700 (PDT), Tomás Ó hÉilidhe
                    >
                    <t...@lavabit.c omwrote:
                    >
                    There are a few guarantees I exploit in the C Standard. For instance,
                    I might write
                    >
                    (unsigned)-1
                    >
                    to get the maximum value for an unsigned integer.
                    >
                    The standard guarantees that values for unsigned integers behave
                    nicely when they wrap in either direction. However, your code will
                    not work for an integer type wider than int. For C89 you probably
                    need (unsigned long) -1L and for C99 (unsigned long long) -1LL.
                    >
                    What makes you think that?
                    >
                    For sake of discussion, let us assume a 16 bit int and a 32 bit long
                    and the common UINT_MAX and ULONG_MAX for these sizes.
                    >
                    The statement
                    unsigned long x = (unsigned)-1;
                    will set x to 65535 (the value of the right hand side) which is
                    0x0000ffff, hardly the maximum value for this unsigned long.
                    I certainly agree that (unsigned) -1 is not going to yield ULONG_MAX.
                    I took your original comment to imply that (unsigned long) -1 would
                    not produce the desired results without the L suffix, that is where my
                    objection stemmed from.

                    --
                    Robert Gamble

                    Comment

                    • Hallvard B Furuseth

                      #11
                      Re: Should embedded systems compilers be trusted

                      Peter Nilsson wrote:
                      Tomás Ó hÉilidhe wrote:
                      > memset(data,-1,sizeof data)
                      >to set all bits in a chunk of memory to 1.
                      >
                      That function need not be available on a freestanding implementation.
                      If it is available though, the behaviour should work as you describe.
                      Only on 2s-complement systems, as Barry pointed out.
                      OTOH (unsigned char)-1 always works.

                      --
                      Hallvard

                      Comment

                      • Walter Roberson

                        #12
                        Re: Should embedded systems compilers be trusted

                        In article <990n04dqe4hr8s l6v81qaambod5ck bg24b@4ax.com>,
                        Barry Schwarz <schwarzb@dqel. comwrote:
                        >On Sun, 20 Apr 2008 04:18:56 -0700 (PDT), Tomás Ó hÉilidhe
                        ><toe@lavabit.c omwrote:
                        >>Also, I might rely on things such as:
                        > memset(data,-1,sizeof data)
                        >>to set all bits in a chunk of memory to 1.
                        >This only works on 2s-complement systems.
                        C89 4.11.6.1 The memset Function

                        Description

                        The memset function copies the value of c (converted to an
                        unsigned char) into each of the first n charactes of the object
                        pointed to by s.


                        From this we can deduce that memset with value -1 will write UCHAR_MAX
                        to the n locations.

                        Is there ever a time when UCHAR_MAX is not all bits 1? The definition
                        of unsigned (C89 3.1.2.5) indicates that,

                        For each of the signed integer types, there is a corresponding
                        (but different) unsigned integer type (designated by the keyword
                        unsigned) that uses the same amount of storage (including
                        sign information) [...]

                        And doesn't C99 guarantee that unsigned char will have no padding bits
                        or trap representations ?

                        --
                        "Product of a myriad various minds and contending tongues, compact of
                        obscure and minute association, a language has its own abundant and
                        often recondite laws, in the habitual and summary recognition of
                        which scholarship consists." -- Walter Pater

                        Comment

                        • Peter Nilsson

                          #13
                          Re: Should embedded systems compilers be trusted

                          Hallvard B Furuseth wrote:
                          Peter Nilsson wrote:
                          Tom�s � h�ilidhe wrote:
                          memset(data,-1,sizeof data)
                          to set all bits in a chunk of memory to 1.
                          ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^

                          That function need not be available on a
                          freestanding implementation.
                          If it is available though, the behaviour should
                          work as you describe.
                          >
                          Only on 2s-complement systems, as Barry pointed out.
                          The Barry is wrong.
                          OTOH (unsigned char)-1 always works.
                          Which is precisely what memset will do.

                          7.21.6.1p2 "The memset function copies the value of c
                          (converted to an unsigned char) ..."

                          --
                          Peter

                          Comment

                          • Barry Schwarz

                            #14
                            Re: Should embedded systems compilers be trusted

                            On Mon, 21 Apr 2008 15:11:17 -0700 (PDT), Peter Nilsson
                            <airia@acay.com .auwrote:
                            >Hallvard B Furuseth wrote:
                            >Peter Nilsson wrote:
                            Tom?s ? h?ilidhe wrote:
                            memset(data,-1,sizeof data)
                            to set all bits in a chunk of memory to 1.
                            ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^
                            >
                            That function need not be available on a
                            freestanding implementation.
                            If it is available though, the behaviour should
                            work as you describe.
                            >>
                            >Only on 2s-complement systems, as Barry pointed out.
                            >
                            >The Barry is wrong.
                            When there was more than one of me, I could always depend on one of
                            the others to catch any mistakes. Now that I've been singularized, I
                            guess I should be more careful. Is there an estate that comes with
                            the title? Or better yet rents and royalties?
                            >
                            >OTOH (unsigned char)-1 always works.
                            >
                            >Which is precisely what memset will do.
                            >
                            >7.21.6.1p2 "The memset function copies the value of c
                            >(converted to an unsigned char) ..."

                            Remove del for email

                            Comment

                            • Walter Roberson

                              #15
                              Re: Should embedded systems compilers be trusted

                              In article <1m6q04l3jdsk2n tn77d3iv3vbehb9 ru0e4@4ax.com>,
                              Barry Schwarz <schwarzb@dqel. comwrote:
                              >On Mon, 21 Apr 2008 15:11:17 -0700 (PDT), Peter Nilsson
                              ><airia@acay.co m.auwrote:
                              >>The Barry is wrong.
                              >When there was more than one of me, I could always depend on one of
                              >the others to catch any mistakes. Now that I've been singularized, I
                              >guess I should be more careful. Is there an estate that comes with
                              >the title? Or better yet rents and royalties?
                              That darned undefined behaviour again! Some people end up with
                              nostral daemons, some people end up with titles and 317 years back
                              taxes...
                              --
                              "Product of a myriad various minds and contending tongues, compact of
                              obscure and minute association, a language has its own abundant and
                              often recondite laws, in the habitual and summary recognition of
                              which scholarship consists." -- Walter Pater

                              Comment

                              Working...