another very basic question :-)

Discussion in 'C Programming' started by sagi, Sep 26, 2008.

  1. sagi

    sagi Guest

    Hello erveryone,I am a newcomer here and the word of c.
    Here I have a question confused me a lot that when I read codes I
    found some declaration like that:
    "int regcomp(regex_t *restrict comoiled, const char *restrict
    parttern, int cflags) "
    or something like that
    " int strnlen(const char FAR *s, int count)"
    what does the "restrict" or "FAR" means?

    --thanks advance
    sagi, Sep 26, 2008
    #1
    1. Advertising

  2. sagi

    James Kuyper Guest

    sagi wrote:
    > Hello erveryone,I am a newcomer here and the word of c.
    > Here I have a question confused me a lot that when I read codes I
    > found some declaration like that:
    > "int regcomp(regex_t *restrict comoiled, const char *restrict
    > parttern, int cflags) "
    > or something like that
    > " int strnlen(const char FAR *s, int count)"
    > what does the "restrict" or "FAR" means?


    FAR is not part of standard C. I believe that it is either a keyword or
    a macro. Either way, it only works on certain systems (which don't
    include any system I write programs for). You would get a better answer
    than I could give you by asking in a newsgroup for the appropriate
    compiler or operating system.

    To understand the restrict keyword, consider the following function. It
    takes as arguments a list of characters, and a string, and it adds 1 to
    any character in the string which matches one of the characters in the list.

    void blankchars(const char blanklist[], char string[])
    {
    if(blanklist == NULL || string == NULL)
    return;
    for( ; *blanklist; blanklist++)
    {
    for(size_t i=0; string; i++)
    {
    if(string == *blanklist)
    string++;
    }
    }
    }

    What happens if this function is called as follows? :

    char alphabet[] = "abcde";
    blankchars(alphabet, alphabet);

    On my home computer, the result of this call will be that alphabet now
    contains the string "bddff". Do you understand why?

    Well, that is probably not what anyone would want the function to do. In
    fact, there's no reasonable thing for the function to do when the
    blanklist and the string overlap in any way.

    You might think that it should check for overlap between the blanklist
    and the output string. The obvious way to do this would seem to be
    compare blanklist, string, and strlen(blanklist) and strlen(string).
    Unfortunately, if blanklist and string do NOT overlap, then comparing
    them with <, >, <=, >= or by subtracting them has behavior that is not
    defined by the C standard. On many machines it will work as you might
    expect, but on many real machines, it will produce erroneous results or
    possibly even cause your program to abort().

    You can compare pointers to different arrays for equality, and there's a
    perfectly portable way to check for overlap that makes use of that fact.
    Just compare a pointer to every character in one string for equality
    with pointers to the starting and ending characters of the other string,
    and vice versa. However, it's rather inefficient.

    The simplest approach is simply to document that the function is not
    guaranteed to work properly if there's any overlap between the strings
    pointed at by its two arguments. This is a very popular choice, and it's
    the one take by the C standard library itself in most cases like that.

    However, just because you've documented that restriction, doesn't mean
    that that compiler knows anything about it. Because you've decided not
    to worry about overlapping arguments, you could have re-written the
    innermost loop as follows:

    int c = *blanklist;

    for(size_t i; string; i++)
    {
    if(string == c)
    string = ' ';
    }

    When there is no overlap, this code produces exactly the same result as
    the original program. This is a very simple optimization, and under
    other circumstances, virtually any modern compiler would perform
    optimizations like this one for you, even at the lowest optimization levels.

    However, in this particular circumstance, the compiler cannot perform
    this optimization for you. The compiler has to generate code which will
    work as required by the C standard, even if string and *blanklist
    refer to the same character, and that's not the case for the optimized
    version of the code. With the optimized version, blankchars(alphabet,
    alphabet) would produce "fffff" (on my machine). The compiler thinks
    it's important to make sure that this case produces "bddff", and will
    therefore not perform the optimization. It doesn't know that you don't
    care about that case.

    This is where "restrict" comes in. If we change the function declaration to

    void blankchars(const char restrict blanklist[], char restrict string[])

    then this tells the compiler that developers and users of blankchars()
    will work together to make sure that string and *blanklist never
    refer to the same object. That gives the compiler permission to perform
    optimizations like the one above.

    The down side of 'restrict' is that, if the requirements it imposes are
    violated, the behavior is undefined. It's no longer the case that we can
    say that the result of calling blankchars(alphabet, alphabet) is to set
    alphabet to "bddff". It is now technically possible that just about
    anything could happen, including causing your program to abort.

    In this particular case, it is most likely to produce "fffff", but in
    more complicated cases, the problems created by the permitted
    optimizations could be arbitrarily bad. However, to be fair, in those
    more complicated cases, the problems would probably also be pretty bad
    if the "restrict" keyword was not used.
    James Kuyper, Sep 26, 2008
    #2
    1. Advertising

  3. sagi

    MisterE Guest

    sagi wrote:
    > Hello erveryone,I am a newcomer here and the word of c.
    > Here I have a question confused me a lot that when I read codes I
    > found some declaration like that:
    > "int regcomp(regex_t *restrict comoiled, const char *restrict
    > parttern, int cflags) "
    > or something like that
    > " int strnlen(const char FAR *s, int count)"
    > what does the "restrict" or "FAR" means?


    FAR (and often many other ones you will see like NEAR DATA IDATA XDATA
    RDATA etc. even FAR FAR are basically special compiler depedant things
    which tell the compiler what sort of memory is being pointed to. This
    is most common on embedded systems which can have internal RAM, external
    RAM, a second external RAM chip at different addresses etc.

    For example its typical for an embedded processor to have internal RAM
    and external ram. So you might be able to declare variables like:

    int foo[32];
    int FAR foo[32];

    one will take up space in internal ram and one in external ram, it all
    depends on the compiler. The compiler will have documentation about
    what it actually does. Typically pointers to external ram may actually
    be of different size or need to page out memory etc so they also use
    the FAR
    MisterE, Sep 26, 2008
    #3
  4. sagi

    REH Guest

    On Sep 26, 6:04 pm, MisterE <> wrote:
    > FAR (and often many other ones you will see like NEAR DATA IDATA XDATA
    > RDATA etc. even FAR FAR are basically special compiler depedant things
    > which tell the compiler what sort of memory is being pointed to. This
    > is most common on embedded systems which can have internal RAM, external
    > RAM, a second external RAM chip at different addresses etc.
    >
    > For example its typical for an embedded processor to have internal RAM
    > and external ram. So you might be able to declare variables like:
    >
    > int foo[32];
    > int FAR foo[32];
    >
    > one will take up space in internal ram and one in external ram, it all
    > depends on the compiler. The compiler will have documentation about
    > what it actually does. Typically pointers to external ram may actually
    > be of different size or need to page out memory etc so they also use
    > the FAR


    OT, but it is more likely he is using a compiler for a segmented
    architecture, like DOS. FAR doesn't indicate any particular type of
    RAM. It indicated a far pointer, which is one that contains both the
    segment and offset of the address.

    REH
    REH, Sep 27, 2008
    #4
    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. Raymond Arthur St. Marie II of III

    very Very VERY dumb Question About The new Set( ) 's

    Raymond Arthur St. Marie II of III, Jul 23, 2003, in forum: Python
    Replies:
    4
    Views:
    454
    Raymond Hettinger
    Jul 27, 2003
  2. aghazalp

    very very basic question

    aghazalp, Apr 2, 2006, in forum: Python
    Replies:
    6
    Views:
    334
    aghazalp
    Apr 2, 2006
  3. shanx__=|;-

    very very very long integer

    shanx__=|;-, Oct 16, 2004, in forum: C Programming
    Replies:
    19
    Views:
    1,594
    Merrill & Michele
    Oct 19, 2004
  4. Peter

    Very very very basic question

    Peter, Feb 8, 2005, in forum: C Programming
    Replies:
    14
    Views:
    503
    Dave Thompson
    Feb 14, 2005
  5. mdh

    A very **very** basic question

    mdh, Sep 25, 2008, in forum: C Programming
    Replies:
    57
    Views:
    1,197
    August Karlstrom
    Sep 26, 2008
Loading...

Share This Page