Should embedded systems compilers be trusted

Discussion in 'C Programming' started by Tomás Ó hÉilidhe, Apr 20, 2008.

  1. 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.
    Tomás Ó hÉilidhe, Apr 20, 2008
    #1
    1. Advertising

  2. On Sun, 20 Apr 2008 04:18:56 -0700 (PDT), 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.


    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
    Barry Schwarz, Apr 20, 2008
    #2
    1. Advertising

  3. On Apr 20, 2:28 pm, Barry Schwarz <> wrote:
    > On Sun, 20 Apr 2008 04:18:56 -0700 (PDT), 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.

    >
    > 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
    Robert Gamble, Apr 20, 2008
    #3
  4. 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
    Peter Nilsson, Apr 20, 2008
    #4
  5. On Sun, 20 Apr 2008 15:21:23 -0700 (PDT), Robert Gamble
    <> wrote:

    >On Apr 20, 2:28 pm, Barry Schwarz <> wrote:
    >> On Sun, 20 Apr 2008 04:18:56 -0700 (PDT), 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.

    >>
    >> 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
    Barry Schwarz, Apr 21, 2008
    #5
  6. Jack Klein <> writes:
    > On Sun, 20 Apr 2008 04:18:56 -0700 (PDT), Tomás Ó hÉilidhe
    > <> wrote 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_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Apr 21, 2008
    #6
  7. On Apr 20, 11:59 pm, Barry Schwarz <> wrote:
    > On Sun, 20 Apr 2008 15:21:23 -0700 (PDT), Robert Gamble
    >
    >
    >
    > <> wrote:
    > >On Apr 20, 2:28 pm, Barry Schwarz <> wrote:
    > >> On Sun, 20 Apr 2008 04:18:56 -0700 (PDT), 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.

    >
    > >> 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
    Robert Gamble, Apr 21, 2008
    #7
  8. 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
    Hallvard B Furuseth, Apr 21, 2008
    #8
  9. In article <>,
    Barry Schwarz <> wrote:
    >On Sun, 20 Apr 2008 04:18:56 -0700 (PDT), Tomás Ó hÉilidhe
    ><> wrote:


    >>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
    Walter Roberson, Apr 21, 2008
    #9
  10. 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
    Peter Nilsson, Apr 21, 2008
    #10
  11. On Mon, 21 Apr 2008 15:11:17 -0700 (PDT), Peter Nilsson
    <> wrote:

    >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
    Barry Schwarz, Apr 22, 2008
    #11
  12. In article <>,
    Barry Schwarz <> wrote:
    >On Mon, 21 Apr 2008 15:11:17 -0700 (PDT), Peter Nilsson
    ><> wrote:


    >>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
    Walter Roberson, Apr 22, 2008
    #12
  13. Barry Schwarz writes:
    >On Mon, 21 Apr 2008 15:11:17 -0700 (PDT), Peter Nilsson
    ><> wrote:
    >>Hallvard B Furuseth wrote:
    >>>Only on 2s-complement systems, as Barry pointed out.

    >>The Barry is wrong.


    Yup, sorry.

    > 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.


    It's good to have company though.

    --
    Hallvard
    Hallvard B Furuseth, Apr 22, 2008
    #13
  14. Tomás Ó hÉilidhe

    Walter Banks Guest

    Tomás Ó hÉilidhe wrote:

    > 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.


    Many (most) of the C compilers for small processors have
    extensions specific to the target families they support. Of these
    three issues.
    1) int's 16 bit most will have at least an option to give you
    16 bit ints many with have size specific declarations.

    2) 32 bit longs. As with ints it will be available on most
    compilers. If 32 bit math is needed you may want to be
    very sure that a PIC 16F684 is the part you want to use.

    3) conversion between signed and unsigned will likely be fine.

    Re-entrant functions and dynamic memory allocation in
    many small embedded processors may not be available.
    Some of the small processors may not have the underlying
    hardware support but the real reason is both re-entrant
    function support and dynamic memory use in most small
    embedded applications may not be good design practice.

    Regards,


    --
    Walter Banks
    Byte Craft Limited
    Tel. (519) 888-6911
    Fax (519) 746 6751
    http://www.bytecraft.com
    Walter Banks, Apr 22, 2008
    #14
  15. On Apr 21, 10:14 pm, -cnrc.gc.ca (Walter Roberson)
    wrote:

    > 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.



    That's right. I actually put a hell of a lot of thought into this a
    few months ago. Things are a little hairy simply because memset takes
    an int rather than an unsigned char.

    Giving it an int value of -1 will always result in it writing
    UCHAR_MAX, and UCHAR_MAX will always be all-bits-one without any
    padding.

    I also went to the bother of writing a memset wrapper which would
    allow you to give it an unsigned char.
    Tomás Ó hÉilidhe, Apr 23, 2008
    #15
  16. On Apr 21, 7:42 am, Keith Thompson <> wrote:

    > 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.



    Exactly; your above line of code will fail to compile with the PIC C
    compiler.
    Tomás Ó hÉilidhe, Apr 23, 2008
    #16
  17. Tomás Ó hÉilidhe

    Ian Collins Guest

    Tomás Ó hÉilidhe wrote:
    > On Apr 21, 7:42 am, Keith Thompson <> wrote:
    >
    >> 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.

    >
    >
    > Exactly; your above line of code will fail to compile with the PIC C
    > compiler.


    That's a bit of a (horrible) bug. Every embedded compiler I've used put
    file scope const items in a read only segment, but not function scope ones.

    --
    Ian Collins.
    Ian Collins, Apr 23, 2008
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mike
    Replies:
    2
    Views:
    612
  2. Replies:
    3
    Views:
    437
    Jack Klein
    May 12, 2005
  3. idiot
    Replies:
    0
    Views:
    295
    idiot
    Aug 30, 2006
  4. geletine

    commercial c compilers vs free c compilers

    geletine, Jul 2, 2006, in forum: C Programming
    Replies:
    33
    Views:
    1,295
  5. Philipp Klaus Krause

    Benchmarking C compilers for embedded systems

    Philipp Klaus Krause, Sep 19, 2011, in forum: C Programming
    Replies:
    8
    Views:
    960
    Walter Banks
    Sep 30, 2011
Loading...

Share This Page