character assignment

Discussion in 'C Programming' started by CptDondo, Jan 2, 2007.

  1. CptDondo

    CptDondo Guest

    I came across this bit of code:

    char devname[4] = "wl0";
    ....
    devname[2]++;

    This looks wrong to me.... I am chasing a bad pointer issue in this
    code, and I suspect this is not valid C.

    --Yan
     
    CptDondo, Jan 2, 2007
    #1
    1. Advertising

  2. "CptDondo" <> wrote in message
    news:...
    >I came across this bit of code:
    >
    > char devname[4] = "wl0";
    > ...
    > devname[2]++;
    >
    > This looks wrong to me.... I am chasing a bad pointer issue in this code,
    > and I suspect this is not valid C.


    The second assignment makes sense. The collation sequence for the ASCII
    digits is linear, so someone is trying to go from , for example, "wl0" to
    "wl1".

    The first assigment doesn't make sense to me. "wl0" (which will include a
    zero terminator) is a statically allocated string managed by the compiler.
    I'm not aware that a typical compiler will allow this syntax. The string
    should have the type of (char *), perhaps with const.

    How about:

    char devname[4] = {'w', 'l', '0', 0};

    ?

    And there are no warnings or errors from the compiler?
     
    David T. Ashley, Jan 2, 2007
    #2
    1. Advertising

  3. CptDondo

    CptDondo Guest

    David T. Ashley wrote:
    > "CptDondo" <> wrote in message
    > news:...
    >> I came across this bit of code:
    >>
    >> char devname[4] = "wl0";
    >> ...
    >> devname[2]++;
    >>
    >> This looks wrong to me.... I am chasing a bad pointer issue in this code,
    >> and I suspect this is not valid C.

    >
    > The second assignment makes sense. The collation sequence for the ASCII
    > digits is linear, so someone is trying to go from , for example, "wl0" to
    > "wl1".


    Right - except, as you point out, the string is static, so I don't see
    how the bloody thing is incremented later.

    >
    > The first assigment doesn't make sense to me. "wl0" (which will include a
    > zero terminator) is a statically allocated string managed by the compiler.
    > I'm not aware that a typical compiler will allow this syntax. The string
    > should have the type of (char *), perhaps with const.
    >
    > How about:
    >
    > char devname[4] = {'w', 'l', '0', 0};


    OK, I'll try that.

    >
    > ?
    >
    > And there are no warnings or errors from the compiler?
    >
    >


    None that I've seen, but the development environment hides a lot of
    information. As it apparently works for the developer, but not for me,
    there resulting errors may well be gcc-version dependent.

    In the older, working version of the code, they assign

    char *devname = "wl0";

    and then increment that. (??? This really makes no sense.)

    I'm going to rewrite it correctly, and see if that fixes the issue.
     
    CptDondo, Jan 2, 2007
    #3
  4. In article <>,
    David T. Ashley <> wrote:
    >"CptDondo" <> wrote in message
    >news:...
    >>I came across this bit of code:


    >> char devname[4] = "wl0";


    >The first assigment doesn't make sense to me. "wl0" (which will include a
    >zero terminator) is a statically allocated string managed by the compiler.
    >I'm not aware that a typical compiler will allow this syntax.


    char *devname = "wl0";

    would be the case of a (theoretically read-only) string managed by
    the compiler. (If my memory holds, the compiler is not -required- to
    statically allocate the string... that's just by far the easiest way to
    meet the lifetime requirements.)


    char devname[4] = "wl0";

    is completely valid C. The C standard specifically indicates that
    an array of char may be initialized by a string literal, with
    successive elements of the literal being assigned into successive
    elements of the array. The resulting array will be writable.
    --
    There are some ideas so wrong that only a very intelligent person
    could believe in them. -- George Orwell
     
    Walter Roberson, Jan 2, 2007
    #4
  5. CptDondo

    Mike Wahler Guest

    "David T. Ashley" <> wrote in message
    news:...
    > "CptDondo" <> wrote in message
    > news:...
    >>I came across this bit of code:
    >>
    >> char devname[4] = "wl0";
    >> ...
    >> devname[2]++;
    >>
    >> This looks wrong to me.... I am chasing a bad pointer issue in this code,
    >> and I suspect this is not valid C.

    >
    > The second assignment makes sense. The collation sequence for the ASCII
    > digits is linear, so someone is trying to go from , for example, "wl0" to
    > "wl1".


    Yes, and the language guarantees that the digit characters ('0'
    through '9') do indeed have consecutive values.

    >
    > The first assigment doesn't make sense to me.


    The first line is not an assignment, it's an initialization,
    and is indeed valid. It creates an array of four characters,
    initializes the first with 'w', the second with '1', the third
    with '0', and the fourth with zero. (i.e. a zero-terminated
    string).

    > "wl0" (which will include a zero terminator) is a statically allocated
    > string managed by the compiler.


    ... which is placed in the array 'devname'.

    > I'm not aware that a typical compiler will allow this syntax.


    Any conforming compiler must.

    >The string should have the type of (char *), perhaps with const.


    No, that would not be a string. That would be a pointer.

    >
    > How about:
    >
    > char devname[4] = {'w', 'l', '0', 0};


    That is also valid. But what OP posted is just as valid,
    and far more common (I suppose because it's easier to type
    and to read).

    I think you need to do some reading about arrays and pointers
    in C.

    See the reviews at www.accu.org for book selections.

    -Mike

    > And there are no warnings or errors from the compiler?


    There shouldn't be any. Nothing is wrong.

    -Mike
     
    Mike Wahler, Jan 2, 2007
    #5
  6. >>>>> "DTA" == David T Ashley <> writes:

    DTA> "CptDondo" <> wrote in message
    DTA> news:...
    >> I came across this bit of code:
    >>
    >> char devname[4] = "wl0"; ... devname[2]++;
    >>
    >> This looks wrong to me.... I am chasing a bad pointer issue in
    >> this code, and I suspect this is not valid C.


    It is, actually, valid C.

    DTA> The first assigment doesn't make sense to me. "wl0" (which
    DTA> will include a zero terminator) is a statically allocated
    DTA> string managed by the compiler.

    ....which is used as an initializer for the char array that's allocated
    in that line.

    DTA> How about:

    DTA> char devname[4] = {'w', 'l', '0', 0};

    DTA> ?

    Functionally identical to what's there, but a lot harder to make sense of.

    DTA> And there are no warnings or errors from the compiler?

    It's valid C - why should the compiler complain?

    Charlton



    --
    Charlton Wilbur
     
    Charlton Wilbur, Jan 2, 2007
    #6
  7. In article <>,
    CptDondo <> wrote:
    >David T. Ashley wrote:
    >> "CptDondo" <> wrote in message
    >> news:...


    >>> char devname[4] = "wl0";


    >>> devname[2]++;


    >> The second assignment makes sense. The collation sequence for the ASCII
    >> digits is linear, so someone is trying to go from , for example, "wl0" to
    >> "wl1".


    >Right - except, as you point out, the string is static, so I don't see
    >how the bloody thing is incremented later.


    The string is not static. The relevant section of C89 (X3.159-1989)
    is 3.5.7; I don't know the corresponding ISO section number.

    devname[2]++; is not going to create any pointer problems for you.

    However, note that devname will have lifetime appropriate to its
    scope, whereas char *devname = "wl0"; would point to something
    with essentially indefinite lifetime but which is theoretically
    read-only.

    Based on what you have said, the code previously relied upon
    the indefinite lifetime, and relied upon literals being writable.
    The corresponding correct code would be

    static char devname[4] = "wl0";

    That would only be initialized once, not once per visit to the
    function.
    --
    "law -- it's a commodity"
    -- Andrew Ryan (The Globe and Mail, 2005/11/26)
     
    Walter Roberson, Jan 2, 2007
    #7
  8. >>>>> "CD" == CptDondo <> writes:

    CD> Right - except, as you point out, the string is static, so I
    CD> don't see how the bloody thing is incremented later.

    The string literal is used as an initializer for the array that's
    allocated.

    CD> In the older, working version of the code, they assign

    CD> char *devname = "wl0";

    CD> and then increment that. (??? This really makes no sense.)

    When you write

    char devname[4] = "wl0";

    you are allocating an array of 4 chars and initializing it to 'w',
    'l', '0', 0. That char string is modifiable, and has automatic
    storage duration. In many implementations, it would be stored on the
    stack.

    When you write

    char *devname = "wl0";

    you allocate a pointer that points to that string literal. The
    compiler may store it anywhere it wants; you can't modify it without
    invoking undefined behavior. The pointer variable has automatic
    storage duration. In some implementations, the string would be stored
    in a read-only segment of the executable.

    CD> I'm going to rewrite it correctly, and see if that fixes the
    CD> issue.

    char devname[4] = "wl0"; *is* written correctly.

    Charlton


    --
    Charlton Wilbur
     
    Charlton Wilbur, Jan 2, 2007
    #8
  9. CptDondo

    Al Balmer Guest

    On Tue, 02 Jan 2007 11:52:27 -0800, CptDondo <>
    wrote:

    >I came across this bit of code:
    >
    >char devname[4] = "wl0";
    >...
    >devname[2]++;
    >
    >This looks wrong to me.... I am chasing a bad pointer issue in this
    >code, and I suspect this is not valid C.
    >

    Keep looking <g>. The expression is one I would avoid, but it's not
    causing your problem.

    --
    Al Balmer
    Sun City, AZ
     
    Al Balmer, Jan 2, 2007
    #9
  10. "Walter Roberson" <-cnrc.gc.ca> wrote in message
    news:eneer0$kt7$...
    >
    >>The first assigment doesn't make sense to me. "wl0" (which will include a
    >>zero terminator) is a statically allocated string managed by the compiler.
    >>I'm not aware that a typical compiler will allow this syntax.

    >
    > char *devname = "wl0";
    >
    > would be the case of a (theoretically read-only) string managed by
    > the compiler. (If my memory holds, the compiler is not -required- to
    > statically allocate the string... that's just by far the easiest way to
    > meet the lifetime requirements.)
    >
    > char devname[4] = "wl0";
    >
    > is completely valid C. The C standard specifically indicates that
    > an array of char may be initialized by a string literal, with
    > successive elements of the literal being assigned into successive
    > elements of the array. The resulting array will be writable.


    Thanks for the correction. I've never seen that initialization syntax.

    I'm only familiar with:

    char *p = "I like coconuts and grapes.";

    and it was my understanding that in that case that compiler was assigning a
    pointer into a static string pool.

    But I may be wrong there again, too! Beat me up more if I blew that one,
    too!

    Thanks.
     
    David T. Ashley, Jan 2, 2007
    #10
  11. In article <>,
    David T. Ashley <> wrote:

    >I'm only familiar with:
    >
    >char *p = "I like coconuts and grapes.";
    >
    >and it was my understanding that in that case that compiler was assigning a
    >pointer into a static string pool.
    >
    >But I may be wrong there again, too! Beat me up more if I blew that one,
    >too!


    You are right, in that case the string may be in read-only memory and
    (I think) shared with other strings.

    -- Richard


    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
     
    Richard Tobin, Jan 2, 2007
    #11
  12. In article <eneho1$1l50$>,
    Richard Tobin <> wrote:
    >In article <>,
    >David T. Ashley <> wrote:


    >>I'm only familiar with:


    >>char *p = "I like coconuts and grapes.";


    >>and it was my understanding that in that case that compiler was assigning a
    >>pointer into a static string pool.


    >You are right, in that case the string may be in read-only memory and
    >(I think) shared with other strings.


    In C89, literal strings need not be distinct, and need not be writable.
    But in C89, I cannot find any indication of the scope or lifetime
    of a string literal, so I do not think it is correct to say that
    the compiler is necessarily "assigning a pointer into a static string pool".

    There must be -something- about the lifetime, as it is well understood
    that pointers to literals may be returned and may be stored and passed
    around. The common usages are such that string literals must have
    a lifetime "as if" equivilent to that of static variables, but if the
    compiler can determine that a particular literal's address is not
    being squirreled away, I see no documented limitation that would
    prevent the compiler from effectively making the string literal local
    to a routine -- possibly even coding the contents right into
    the instruction space. I have these flashbacks to disassembling
    in my Z80 days...
    --
    Is there any thing whereof it may be said, See, this is new? It hath
    been already of old time, which was before us. -- Ecclesiastes
     
    Walter Roberson, Jan 2, 2007
    #12
  13. CptDondo

    Ben Pfaff Guest

    -cnrc.gc.ca (Walter Roberson) writes:

    > In C89, literal strings need not be distinct, and need not be writable.
    > But in C89, I cannot find any indication of the scope or lifetime
    > of a string literal, so I do not think it is correct to say that
    > the compiler is necessarily "assigning a pointer into a static string pool".


    C89 (or at least a late draft) says:

    A character string literal has static storage duration and
    type ``array of char,'' and is initialized with the given
    characters.
    --
    int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    );while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    );}return 0;}
     
    Ben Pfaff, Jan 2, 2007
    #13
  14. CptDondo

    CBFalconer Guest

    Walter Roberson wrote:
    >

    .... snip ...
    > prevent the compiler from effectively making the string literal
    > local to a routine -- possibly even coding the contents right into
    > the instruction space. I have these flashbacks to disassembling
    > in my Z80 days...


    What makes you think such coding into instructions isn't static
    storage?

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>
     
    CBFalconer, Jan 3, 2007
    #14
  15. In article <>,
    CBFalconer <> wrote:
    >Walter Roberson wrote:


    >... snip ...
    >> prevent the compiler from effectively making the string literal
    >> local to a routine -- possibly even coding the contents right into
    >> the instruction space. I have these flashbacks to disassembling
    >> in my Z80 days...


    >What makes you think such coding into instructions isn't static
    >storage?


    a) It wouldn't be a "static pool of strings";
    b) In my Z80 days, bank switching was used to extend memory, and
    it was not uncommon for a swappable bank to include instructions. It
    is debatable as to whether such a situation would be "static
    storage" or not.
    --
    I was very young in those days, but I was also rather dim.
    -- Christopher Priest
     
    Walter Roberson, Jan 3, 2007
    #15
  16. CptDondo

    WaterWalk Guest

    CptDondo wrote:
    > I came across this bit of code:
    >
    > char devname[4] = "wl0";
    > ...
    > devname[2]++;
    >
    > This looks wrong to me.... I am chasing a bad pointer issue in this
    > code, and I suspect this is not valid C.
    >


    Both are valid C. I remember that old C compilers would require this:
    static char devname[4] = "wI0";
    But it seems that since c89 this restraint no longer exists.
     
    WaterWalk, Jan 5, 2007
    #16
    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. Velvet
    Replies:
    9
    Views:
    14,978
    Joerg Jooss
    Jan 19, 2006
  2. Giuseppe

    Re: Character assignment causes bus error

    Giuseppe, Jun 24, 2003, in forum: C Programming
    Replies:
    1
    Views:
    1,552
    Giuseppe
    Jun 24, 2003
  3. nagy
    Replies:
    36
    Views:
    1,063
    Terry Reedy
    Jul 20, 2006
  4. gk245
    Replies:
    10
    Views:
    1,041
    Peter Shaggy Haywood
    Apr 22, 2006
  5. Chris
    Replies:
    34
    Views:
    1,604
Loading...

Share This Page