Compile Time Error Checking?

Discussion in 'C Programming' started by Bryan Crouse, Sep 4, 2007.

  1. Bryan Crouse

    Bryan Crouse Guest

    I am looking a way to do error checking on a string at compile time,
    and if the string isn't the correct length have then have the compiler
    throw an error.

    I am working an embedded software that will require individual builds
    for each device so that the device serial number is contained in the
    program memory. To do this, the C application must be compiled with
    the serial number assigned to a variable within the source code file.
    I would like to provide compile time error checking within the .c file
    if possible so that if the length of the string is not correct, then
    the build process will fail and there is no risk of having an
    executable that has a bad serial number.

    Has anyone heard of this or done this sort of thing? Any advice would
    be greatly appreciated.

    Thanks!
     
    Bryan Crouse, Sep 4, 2007
    #1
    1. Advertising

  2. Bryan Crouse

    jacob navia Guest

    Bryan Crouse wrote:
    > I am looking a way to do error checking on a string at compile time,
    > and if the string isn't the correct length have then have the compiler
    > throw an error.
    >
    > I am working an embedded software that will require individual builds
    > for each device so that the device serial number is contained in the
    > program memory. To do this, the C application must be compiled with
    > the serial number assigned to a variable within the source code file.
    > I would like to provide compile time error checking within the .c file
    > if possible so that if the length of the string is not correct, then
    > the build process will fail and there is no risk of having an
    > executable that has a bad serial number.
    >
    > Has anyone heard of this or done this sort of thing? Any advice would
    > be greatly appreciated.
    >
    > Thanks!
    >


    Say the serial number has 9 positions:

    char SerialNumnber[] = "12345678";

    Then, declare an array of 1 position like this

    int m[sizeof(SerialNumber) == 9];

    If sizeof(SerialNumber) != 8 the expression will yield
    zero, and you can't declare an array of negative
    size or zero.

    --------------------------------------------

    I hope it works!
     
    jacob navia, Sep 4, 2007
    #2
    1. Advertising

  3. Bryan Crouse

    Bryan Crouse Guest

    On Sep 4, 9:07 am, Bryan Crouse <> wrote:
    > I am looking a way to do error checking on a string at compile time,
    > and if the string isn't the correct length have then have the compiler
    > throw an error.
    >
    > I am working an embedded software that will require individual builds
    > for each device so that the device serial number is contained in the
    > program memory. To do this, the C application must be compiled with
    > the serial number assigned to a variable within the source code file.
    > I would like to provide compile time error checking within the .c file
    > if possible so that if the length of the string is not correct, then
    > the build process will fail and there is no risk of having an
    > executable that has a bad serial number.
    >
    > Has anyone heard of this or done this sort of thing? Any advice would
    > be greatly appreciated.
    >
    > Thanks!


    Whoops... An article on compile time assertions can be found here:
    http://www.ddj.com/architect/184401873
     
    Bryan Crouse, Sep 4, 2007
    #3
  4. Bryan Crouse

    Eric Sosman Guest

    Bryan Crouse wrote On 09/04/07 10:07,:
    > I am looking a way to do error checking on a string at compile time,
    > and if the string isn't the correct length have then have the compiler
    > throw an error.
    >
    > I am working an embedded software that will require individual builds
    > for each device so that the device serial number is contained in the
    > program memory. To do this, the C application must be compiled with
    > the serial number assigned to a variable within the source code file.
    > I would like to provide compile time error checking within the .c file
    > if possible so that if the length of the string is not correct, then
    > the build process will fail and there is no risk of having an
    > executable that has a bad serial number.
    >
    > Has anyone heard of this or done this sort of thing? Any advice would
    > be greatly appreciated.


    Here's one horrid hack:

    char serial[] = "..."; /* should be 42 characters */

    /* If the following line produces an error, it means
    * that `serial' (above) does not have the expected
    * length. Pay no attention to the text of the error
    * message the compiler issues; the problem is with
    * the definition of `serial'.
    */
    static char fake[ (sizeof serial == 42 + 1) * 2 - 1 ];

    If the serial number is indeed 42 characters long (plus one
    for the trailing '\0'), fake[1] is a legal array declaration.
    If the length is something other than 42, you get fake[-1] and
    an error message.

    It seems to me, though, that you're attacking the problem
    at the wrong place. This hack can check the length and can
    maybe be extended to check a few other things, but it's not
    going to be easy (or maintainable) to get more thorough
    validation from it. If you've got a rule like "The first
    two characters are upper-case letters, followed by five
    digits and three letters or by six digits and two letters,
    followed by ..." then this technique will be far more trouble
    than it's worth. Instead, consider arranging your build
    procedure so the serial number gets validated by a program
    which then runs the build using that number. (For example,
    it might write the validated number to a small .c file that
    then gets compiled and linked in with the rest, or it might
    compile everything with a `-DSERIAL=AB1234ZX999' option, or
    something of that sort.) I think you'll find this more
    reliable than telling the builders "Edit the file serial.c
    and then rebuild the product. Be sure no one else is trying
    to build it at the same time ..."

    --
     
    Eric Sosman, Sep 4, 2007
    #4
  5. Bryan Crouse

    Flash Gordon Guest

    jacob navia wrote, On 04/09/07 15:28:
    > Bryan Crouse wrote:
    >> I am looking a way to do error checking on a string at compile time,
    >> and if the string isn't the correct length have then have the compiler
    >> throw an error.
    >>
    >> I am working an embedded software that will require individual builds
    >> for each device so that the device serial number is contained in the
    >> program memory. To do this, the C application must be compiled with
    >> the serial number assigned to a variable within the source code file.
    >> I would like to provide compile time error checking within the .c file
    >> if possible so that if the length of the string is not correct, then
    >> the build process will fail and there is no risk of having an
    >> executable that has a bad serial number.
    >>
    >> Has anyone heard of this or done this sort of thing? Any advice would
    >> be greatly appreciated.
    >>
    >> Thanks!
    >>

    >
    > Say the serial number has 9 positions:
    >
    > char SerialNumnber[] = "12345678";
    >
    > Then, declare an array of 1 position like this
    >
    > int m[sizeof(SerialNumber) == 9];
    >
    > If sizeof(SerialNumber) != 8 the expression will yield
    > zero, and you can't declare an array of negative
    > size or zero.
    >
    > --------------------------------------------
    >
    > I hope it works!


    It doesn't work and does not do what you claim. It won't error if the
    string is too long, only if it is too short. A string being too long can
    be just as serious an error. See Eric's post for a solution that will do
    what you claimed.
    --
    Flash Gordon
     
    Flash Gordon, Sep 4, 2007
    #5
  6. Bryan Crouse

    jacob navia Guest

    Flash Gordon wrote:
    > jacob navia wrote, On 04/09/07 15:28:
    >> Bryan Crouse wrote:
    >>> I am looking a way to do error checking on a string at compile time,
    >>> and if the string isn't the correct length have then have the compiler
    >>> throw an error.
    >>>
    >>> I am working an embedded software that will require individual builds
    >>> for each device so that the device serial number is contained in the
    >>> program memory. To do this, the C application must be compiled with
    >>> the serial number assigned to a variable within the source code file.
    >>> I would like to provide compile time error checking within the .c file
    >>> if possible so that if the length of the string is not correct, then
    >>> the build process will fail and there is no risk of having an
    >>> executable that has a bad serial number.
    >>>
    >>> Has anyone heard of this or done this sort of thing? Any advice would
    >>> be greatly appreciated.
    >>>
    >>> Thanks!
    >>>

    >>
    >> Say the serial number has 9 positions:
    >>
    >> char SerialNumnber[] = "12345678";
    >>
    >> Then, declare an array of 1 position like this
    >>
    >> int m[sizeof(SerialNumber) == 9];
    >>
    >> If sizeof(SerialNumber) != 8 the expression will yield
    >> zero, and you can't declare an array of negative
    >> size or zero.
    >>
    >> --------------------------------------------
    >>
    >> I hope it works!

    >
    > It doesn't work and does not do what you claim. It won't error if the
    > string is too long, only if it is too short. A string being too long can
    > be just as serious an error. See Eric's post for a solution that will do
    > what you claimed.


    I forgot the -1
    char SerialNumber[]="123456789";

    int m[(sizeof(SerialNumber) == 9)-1];
     
    jacob navia, Sep 4, 2007
    #6
  7. Bryan Crouse

    Flash Gordon Guest

    jacob navia wrote, On 04/09/07 19:26:
    > Flash Gordon wrote:
    >> jacob navia wrote, On 04/09/07 15:28:
    >>> Bryan Crouse wrote:
    >>>> I am looking a way to do error checking on a string at compile time,
    >>>> and if the string isn't the correct length have then have the compiler
    >>>> throw an error.
    >>>>
    >>>> I am working an embedded software that will require individual builds
    >>>> for each device so that the device serial number is contained in the
    >>>> program memory. To do this, the C application must be compiled with
    >>>> the serial number assigned to a variable within the source code file.
    >>>> I would like to provide compile time error checking within the .c file
    >>>> if possible so that if the length of the string is not correct, then
    >>>> the build process will fail and there is no risk of having an
    >>>> executable that has a bad serial number.
    >>>>
    >>>> Has anyone heard of this or done this sort of thing? Any advice would
    >>>> be greatly appreciated.
    >>>>
    >>>> Thanks!
    >>>>
    >>>
    >>> Say the serial number has 9 positions:
    >>>
    >>> char SerialNumnber[] = "12345678";
    >>>
    >>> Then, declare an array of 1 position like this
    >>>
    >>> int m[sizeof(SerialNumber) == 9];
    >>>
    >>> If sizeof(SerialNumber) != 8 the expression will yield
    >>> zero, and you can't declare an array of negative
    >>> size or zero.
    >>>
    >>> --------------------------------------------
    >>>
    >>> I hope it works!

    >>
    >> It doesn't work and does not do what you claim. It won't error if the
    >> string is too long, only if it is too short. A string being too long
    >> can be just as serious an error. See Eric's post for a solution that
    >> will do what you claimed.

    >
    > I forgot the -1
    > char SerialNumber[]="123456789";
    >
    > int m[(sizeof(SerialNumber) == 9)-1];


    Actually, I misread your code and reported it as wrong for the wrong reason.
    --
    Flash Gordon
     
    Flash Gordon, Sep 4, 2007
    #7
  8. Bryan Crouse

    Eric Sosman Guest

    Flash Gordon wrote On 09/04/07 13:53,:
    > jacob navia wrote, On 04/09/07 15:28:
    >
    >>Bryan Crouse wrote:
    >>
    >>>I am looking a way to do error checking on a string at compile time,
    >>>and if the string isn't the correct length have then have the compiler
    >>>throw an error.
    >>>
    >>>I am working an embedded software that will require individual builds
    >>>for each device so that the device serial number is contained in the
    >>>program memory. To do this, the C application must be compiled with
    >>>the serial number assigned to a variable within the source code file.
    >>>I would like to provide compile time error checking within the .c file
    >>>if possible so that if the length of the string is not correct, then
    >>>the build process will fail and there is no risk of having an
    >>>executable that has a bad serial number.
    >>>
    >>>Has anyone heard of this or done this sort of thing? Any advice would
    >>>be greatly appreciated.
    >>>
    >>>Thanks!
    >>>

    >>
    >>Say the serial number has 9 positions:
    >>
    >>char SerialNumnber[] = "12345678";
    >>
    >>Then, declare an array of 1 position like this
    >>
    >>int m[sizeof(SerialNumber) == 9];
    >>
    >>If sizeof(SerialNumber) != 8 the expression will yield
    >>zero, and you can't declare an array of negative
    >>size or zero.
    >>
    >>--------------------------------------------
    >>
    >>I hope it works!

    >
    >
    > It doesn't work and does not do what you claim. It won't error if the
    > string is too long, only if it is too short. A string being too long can
    > be just as serious an error. See Eric's post for a solution that will do
    > what you claimed.


    I see a minor typo in Jacob's solution (oscillating
    between 8 and 9, or between size and length), but no more.
    The idea is the same in both cases. I see no basis for
    claiming that Jacob's method fails on too-long strings.

    The only serious difference I see is that Jacob's
    error-provoker is a [0] dimension and mine is a [-1].
    Both are illegal and will produce diagnostics from a
    conforming compiler. Mine also attempts to arouse the
    ire of a non-conforming compiler (see the recent thread
    "memcpy() where assignment would do?" for a report of
    a compiler that did not complain about a [0] dimension).

    Now that I think of it, there's another difference:
    I made the array static to ensure that it could not be a
    C99-style variable-length array. I don't use VLA's and
    am not conversant with the rules, so I made sure to avoid
    them just in case a zero-element VLA is in fact legal, or
    is an error that wouldn't crop up until run-time.

    --
     
    Eric Sosman, Sep 4, 2007
    #8
  9. Bryan Crouse

    Flash Gordon Guest

    Eric Sosman wrote, On 04/09/07 21:51:
    > Flash Gordon wrote On 09/04/07 13:53,:
    >> jacob navia wrote, On 04/09/07 15:28:


    <snip>

    > I see a minor typo in Jacob's solution (oscillating
    > between 8 and 9, or between size and length), but no more.
    > The idea is the same in both cases. I see no basis for
    > claiming that Jacob's method fails on too-long strings.


    It's not my day. I spotted that I had misread Jacob's code when I saw
    his correction and posted to that effect.
    --
    Flash Gordon
     
    Flash Gordon, Sep 4, 2007
    #9
  10. Bryan Crouse

    Old Wolf Guest

    On Sep 5, 8:51 am, Eric Sosman <> wrote:
    > > jacob navia wrote, On 04/09/07 15:28:
    > >>int m[sizeof(SerialNumber) == 9];

    >
    > Now that I think of it, there's another difference:
    > I made the array static to ensure that it could not be a
    > C99-style variable-length array. I don't use VLA's and
    > am not conversant with the rules, so I made sure to avoid
    > them just in case a zero-element VLA is in fact legal, or
    > is an error that wouldn't crop up until run-time.


    These issues can be avoided by making the array
    a typedef (this also prevents dumb compilers from
    actually wasting memory for the array).
     
    Old Wolf, Sep 5, 2007
    #10
  11. Bryan Crouse

    Ark Khasin Guest

    Eric Sosman wrote:
    > Bryan Crouse wrote On 09/04/07 10:07,:
    >> I am looking a way to do error checking on a string at compile time,
    >> and if the string isn't the correct length have then have the compiler
    >> throw an error.
    >>
    >> I am working an embedded software that will require individual builds
    >> for each device so that the device serial number is contained in the
    >> program memory. To do this, the C application must be compiled with
    >> the serial number assigned to a variable within the source code file.
    >> I would like to provide compile time error checking within the .c file
    >> if possible so that if the length of the string is not correct, then
    >> the build process will fail and there is no risk of having an
    >> executable that has a bad serial number.
    >>
    >> Has anyone heard of this or done this sort of thing? Any advice would
    >> be greatly appreciated.

    >
    > Here's one horrid hack:
    >
    > char serial[] = "..."; /* should be 42 characters */
    >
    > /* If the following line produces an error, it means
    > * that `serial' (above) does not have the expected
    > * length. Pay no attention to the text of the error
    > * message the compiler issues; the problem is with
    > * the definition of `serial'.
    > */
    > static char fake[ (sizeof serial == 42 + 1) * 2 - 1 ];
    >
    > If the serial number is indeed 42 characters long (plus one
    > for the trailing '\0'), fake[1] is a legal array declaration.
    > If the length is something other than 42, you get fake[-1] and
    > an error message.
    >
    > It seems to me, though, that you're attacking the problem
    > at the wrong place. This hack can check the length and can
    > maybe be extended to check a few other things, but it's not
    > going to be easy (or maintainable) to get more thorough
    > validation from it. If you've got a rule like "The first
    > two characters are upper-case letters, followed by five
    > digits and three letters or by six digits and two letters,
    > followed by ..." then this technique will be far more trouble
    > than it's worth. Instead, consider arranging your build
    > procedure so the serial number gets validated by a program
    > which then runs the build using that number. (For example,
    > it might write the validated number to a small .c file that
    > then gets compiled and linked in with the rest, or it might
    > compile everything with a `-DSERIAL=AB1234ZX999' option, or
    > something of that sort.) I think you'll find this more
    > reliable than telling the builders "Edit the file serial.c
    > and then rebuild the product. Be sure no one else is trying
    > to build it at the same time ..."
    >

    I agree that -DSERIAL=AB1234ZX999 is the best ever (though only after a
    post-link massaging of the const section/segment made by the linker alone).

    Still, the usage of it may require validation in the C source.
    In a similar case, I used
    #define MYASSERT(cond) extern int assert_dummy[(cond)?1:-1]
    #define SERIAL_ STRING(SERIAL)
    ( Of course: #define STRING(s) STRING_RAW(s) #define STRING_RAW(s) #s )

    And now the useful part:
    #define SERIAL_LEN (sizeof(SERIAL_)-1) //don't bother to store last '\0'
    MYASSERT(SERIAL_LEN==WHAT_I_WANT);
    char_or_perhaps__uint8_t unique_serial[SERIAL_LEN]=SERIAL_;

    In a way, same Eric's (and, in a way, Jacob's) hack but draped enough to
    look almost attractive :)

    -- Ark
     
    Ark Khasin, Sep 5, 2007
    #11
  12. On Tue, 04 Sep 2007 16:32:10 -0700, Old Wolf <>
    wrote:

    > On Sep 5, 8:51 am, Eric Sosman <> wrote:
    > > > jacob navia wrote, On 04/09/07 15:28:
    > > >>int m[sizeof(SerialNumber) == 9];

    > >
    > > Now that I think of it, there's another difference:
    > > I made the array static to ensure that it could not be a
    > > C99-style variable-length array. I don't use VLA's and
    > > am not conversant with the rules, so I made sure to avoid
    > > them just in case a zero-element VLA is in fact legal, or
    > > is an error that wouldn't crop up until run-time.

    >
    > These issues can be avoided by making the array
    > a typedef (this also prevents dumb compilers from
    > actually wasting memory for the array).


    typedef does not avoid the issue stated; you can (in C99) have a
    typedef for a VLA type, and it is indeed runtime UB, with no required
    diagnostic, if the bound of a VLA type turns out to be zero.

    It may indeed avoid wasting space. At the cost of making the
    assertion, and in particular the error for violating it, even sillier.

    - formerly david.thompson1 || achar(64) || worldnet.att.net
     
    David Thompson, Sep 16, 2007
    #12
  13. Bryan Crouse

    Old Wolf Guest

    On Sep 17, 9:45 am, David Thompson <> wrote:
    > > These issues can be avoided by making the array
    > > a typedef (this also prevents dumb compilers from
    > > actually wasting memory for the array).

    >
    > typedef does not avoid the issue stated; you can (in C99) have a
    > typedef for a VLA type, and it is indeed runtime UB, with no required
    > diagnostic, if the bound of a VLA type turns out to be zero.
    >
    > It may indeed avoid wasting space. At the cost of making the
    > assertion, and in particular the error for violating it, even sillier.


    Well, you would make it a macro, so it doesn't matter
    if it looks silly. You can set up the macro using __LINE__
    to define the typedef name as assert_failed_on_line_213 or
    something similar, so it's clear what the error was.
     
    Old Wolf, Sep 16, 2007
    #13
    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. Ben Ingram
    Replies:
    6
    Views:
    393
    red floyd
    Jan 30, 2004
  2. Qopit

    "Compile time" checking?

    Qopit, Aug 10, 2005, in forum: Python
    Replies:
    22
    Views:
    649
    Benjamin Niemann
    Aug 13, 2005
  3. jlara

    Checking endianess in compile time

    jlara, Jun 6, 2005, in forum: C Programming
    Replies:
    7
    Views:
    386
    Michael Mair
    Jun 7, 2005
  4. Nagaraj
    Replies:
    1
    Views:
    876
    Lionel B
    Mar 1, 2007
  5. Carter
    Replies:
    2
    Views:
    510
    Carter
    Mar 4, 2009
Loading...

Share This Page