initialisation of a char pointer using char *s = "something"

Discussion in 'C Programming' started by Brice Rebsamen, Mar 12, 2008.

  1. Reading the code from showkey.c (from package kbd) I found this type
    of code:

    char *m;
    m = "RAW";

    See below for the complete code. How can this work? I would have used
    strdup, or allocation of the memory for m (static or dynamic) then
    strncpy.

    Thanks
    Brice


    static void
    get_mode(void) {
    char *m;

    if (ioctl(fd, KDGKBMODE, &oldkbmode)) {
    perror("KDGKBMODE");
    exit(1);
    }
    switch(oldkbmode) {
    case K_RAW:
    m = "RAW"; break;
    case K_XLATE:
    m = "XLATE"; break;
    case K_MEDIUMRAW:
    m = "MEDIUMRAW"; break;
    case K_UNICODE:
    m = "UNICODE"; break;
    default:
    m = _("?UNKNOWN?"); break;
    }
    printf(_("kb mode was %s\n"), m);
    if (oldkbmode != K_XLATE) {
    printf(_("[ if you are trying this under X, it might not work\n"
    "since the X server is also reading /dev/console ]\n"));
    }
    printf("\n");
    }
    Brice Rebsamen, Mar 12, 2008
    #1
    1. Advertising

  2. Brice Rebsamen

    Ian Collins Guest

    Brice Rebsamen wrote:
    > Reading the code from showkey.c (from package kbd) I found this type
    > of code:
    >
    > char *m;
    > m = "RAW";
    >

    The character pointer m (which should probably be a const char*) points
    to the string literal "RAW".

    > See below for the complete code. How can this work? I would have used
    > strdup, or allocation of the memory for m (static or dynamic) then
    > strncpy.
    >

    Remember m it a pointer.

    --
    Ian Collins.
    Ian Collins, Mar 12, 2008
    #2
    1. Advertising

  3. "WANG Cong" <> wrote in message
    news:fr7she$std$99.com...
    > On Tue, 11 Mar 2008 21:10:20 -0700,Brice Rebsamen wrote:
    >
    >> Reading the code from showkey.c (from package kbd) I found this type of
    >> code:
    >>
    >> char *m;
    >> m = "RAW";
    >>
    >> See below for the complete code. How can this work? I would have used
    >> strdup, or allocation of the memory for m (static or dynamic) then
    >> strncpy.

    >
    > In C, you should treat the string "RAW" as a pointer to char.

    [...]

    What about treating it as a pointer to a const char?

    [...]
    Chris Thomasson, Mar 12, 2008
    #3
  4. Brice Rebsamen <> wrote:
    > Reading the code from showkey.c (from package kbd) I
    > found this type of code:
    >
    > char *m;
    > m = "RAW";
    >
    > See below for the complete code. How can this work?


    What makes you think it can't?

    I suspect your confusion stems from m not being const
    qualified, and string literals having type char[] in C.

    > I would have used strdup, or allocation of the memory
    > for m (static or dynamic) then strncpy.

    <snip>

    Why bother?

    Take a look at the following and see if the penny drops...

    #include <stdio.h>

    void foo(const char *m)
    {
    puts(m);
    }

    void bar(void)
    {
    const char *m = "Hello"; /* what's the diff? */
    puts(m);
    }

    int main(void)
    {
    foo("Hello");
    bar();
    return 0;
    }

    Given the points I mentioned earlier, realise that
    I could leave out the const-s, though it wouldn't
    be good form.

    --
    Peter
    Peter Nilsson, Mar 12, 2008
    #4
  5. Brice Rebsamen wrote:
    > Reading the code from showkey.c (from package kbd) I found this type
    > of code:
    >
    > char *m;
    > m = "RAW";
    >
    > See below for the complete code. How can this work? I would have used
    > strdup, or allocation of the memory for m (static or dynamic) then
    > strncpy.
    >
    > ...


    This is not a meaningful question. It obviously does work, and my
    immediate response to your question was "how can it not work". You need
    to explain why you find this surprising, then we'll be able to sort out
    your confusion.
    J. J. Farrell, Mar 12, 2008
    #5
  6. On Mar 12, 12:55 pm, Peter Nilsson <> wrote:
    > Brice Rebsamen <> wrote:
    > > Reading the code from showkey.c (from package kbd) I
    > > found this type of code:

    >
    > > char *m;
    > > m = "RAW";

    >
    > > See below for the complete code. How can this work?

    >
    > What makes you think it can't?
    >
    > I suspect your confusion stems from m not being const
    > qualified, and string literals having type char[] in C.
    >
    > > I would have used strdup, or allocation of the memory
    > > for m (static or dynamic) then strncpy.

    >
    > <snip>
    >
    > Why bother?
    >
    > Take a look at the following and see if the penny drops...
    >
    > #include <stdio.h>
    >
    > void foo(const char *m)
    > {
    > puts(m);
    > }
    >
    > void bar(void)
    > {
    > const char *m = "Hello"; /* what's the diff? */
    > puts(m);
    > }
    >
    > int main(void)
    > {
    > foo("Hello");
    > bar();
    > return 0;
    > }
    >
    > Given the points I mentioned earlier, realise that
    > I could leave out the const-s, though it wouldn't
    > be good form.
    >
    > --
    > Peter



    Still I'm confused. Take a look at the following:

    const char *getm1(void) { char m[] = "Hello"; return m; }
    const char *getm2(void) { return "Hello"; }

    getm1 raises a warning about returning the address of a local variable
    and returns a corrupted string. This I have known for a long time. My
    explanation is that the memory is released when the function returns,
    therefore whatever happens to m is undefined (possibly overwritten).
    I don't understand why it's not the case with getm2().
    Brice Rebsamen, Mar 12, 2008
    #6
  7. Brice Rebsamen

    WANG Cong Guest

    On Tue, 11 Mar 2008 21:10:20 -0700,Brice Rebsamen wrote:

    > Reading the code from showkey.c (from package kbd) I found this type of
    > code:
    >
    > char *m;
    > m = "RAW";
    >
    > See below for the complete code. How can this work? I would have used
    > strdup, or allocation of the memory for m (static or dynamic) then
    > strncpy.


    In C, you should treat the string "RAW" as a pointer to char.

    >
    > Thanks
    > Brice
    >
    >
    > static void
    > get_mode(void) {
    > char *m;
    >
    > if (ioctl(fd, KDGKBMODE, &oldkbmode)) {
    > perror("KDGKBMODE");
    > exit(1);
    > }
    > switch(oldkbmode) {
    > case K_RAW:
    > m = "RAW"; break;
    > case K_XLATE:
    > m = "XLATE"; break;
    > case K_MEDIUMRAW:
    > m = "MEDIUMRAW"; break;
    > case K_UNICODE:
    > m = "UNICODE"; break;
    > default:
    > m = _("?UNKNOWN?"); break;



    Hmm, you must have a function named "_", and it takes a (const) char*
    parameter, right?
    WANG Cong, Mar 12, 2008
    #7
  8. On Mar 12, 2:05 pm, Brice Rebsamen <> wrote:
    > On Mar 12, 12:55 pm, Peter Nilsson <> wrote:
    >
    >
    >
    > > Brice Rebsamen <> wrote:
    > > > Reading the code from showkey.c (from package kbd) I
    > > > found this type of code:

    >
    > > > char *m;
    > > > m = "RAW";

    >
    > > > See below for the complete code. How can this work?

    >
    > > What makes you think it can't?

    >
    > > I suspect your confusion stems from m not being const
    > > qualified, and string literals having type char[] in C.

    >
    > > > I would have used strdup, or allocation of the memory
    > > > for m (static or dynamic) then strncpy.

    >
    > > <snip>

    >
    > > Why bother?

    >
    > > Take a look at the following and see if the penny drops...

    >
    > > #include <stdio.h>

    >
    > > void foo(const char *m)
    > > {
    > > puts(m);
    > > }

    >
    > > void bar(void)
    > > {
    > > const char *m = "Hello"; /* what's the diff? */
    > > puts(m);
    > > }

    >
    > > int main(void)
    > > {
    > > foo("Hello");
    > > bar();
    > > return 0;
    > > }

    >
    > > Given the points I mentioned earlier, realise that
    > > I could leave out the const-s, though it wouldn't
    > > be good form.

    >
    > > --
    > > Peter

    >
    > Still I'm confused. Take a look at the following:
    >
    > const char *getm1(void) { char m[] = "Hello"; return m; }
    > const char *getm2(void) { return "Hello"; }
    >
    > getm1 raises a warning about returning the address of a local variable
    > and returns a corrupted string. This I have known for a long time. My
    > explanation is that the memory is released when the function returns,
    > therefore whatever happens to m is undefined (possibly overwritten).
    > I don't understand why it's not the case with getm2().


    Messages come really fast here! I found a clear answer in c-faq 1.32.
    Thanks all.
    Brice Rebsamen, Mar 12, 2008
    #8
  9. Brice Rebsamen

    WANG Cong Guest

    On Tue, 11 Mar 2008 21:52:52 -0700,Chris Thomasson wrote:

    > "WANG Cong" <> wrote in message
    > news:fr7she$std$99.com...
    >> On Tue, 11 Mar 2008 21:10:20 -0700,Brice Rebsamen wrote:
    >>
    >>> Reading the code from showkey.c (from package kbd) I found this type
    >>> of code:
    >>>
    >>> char *m;
    >>> m = "RAW";
    >>>
    >>> See below for the complete code. How can this work? I would have used
    >>> strdup, or allocation of the memory for m (static or dynamic) then
    >>> strncpy.

    >>
    >> In C, you should treat the string "RAW" as a pointer to char.

    > [...]
    >
    > What about treating it as a pointer to a const char?


    Yes, more correct. Its conversion to char* is only permitted for C
    compatibility indeed.
    WANG Cong, Mar 12, 2008
    #9
  10. Brice Rebsamen

    WANG Cong Guest

    On Wed, 12 Mar 2008 07:06:19 +0000,WANG Cong wrote:

    > On Tue, 11 Mar 2008 21:52:52 -0700,Chris Thomasson wrote:
    >
    >> "WANG Cong" <> wrote in message
    >> news:fr7she$std$99.com...
    >>> On Tue, 11 Mar 2008 21:10:20 -0700,Brice Rebsamen wrote:
    >>>
    >>>> Reading the code from showkey.c (from package kbd) I found this type
    >>>> of code:
    >>>>
    >>>> char *m;
    >>>> m = "RAW";
    >>>>
    >>>> See below for the complete code. How can this work? I would have used
    >>>> strdup, or allocation of the memory for m (static or dynamic) then
    >>>> strncpy.
    >>>
    >>> In C, you should treat the string "RAW" as a pointer to char.

    >> [...]
    >>
    >> What about treating it as a pointer to a const char?

    >
    > Yes, more correct. Its conversion to char* is only permitted for C
    > compatibility indeed.


    See also Question 11.8b of C-faq.
    WANG Cong, Mar 12, 2008
    #10
  11. Ian Collins <> writes:
    > Brice Rebsamen wrote:
    >> Reading the code from showkey.c (from package kbd) I found this type
    >> of code:
    >>
    >> char *m;
    >> m = "RAW";
    >>

    > The character pointer m (which should probably be a const char*) points
    > to the string literal "RAW".
    >
    >> See below for the complete code. How can this work? I would have used
    >> strdup, or allocation of the memory for m (static or dynamic) then
    >> strncpy.
    >>

    > Remember m it a pointer.


    I suspect Brice's confusion is based not on the fact that m is a
    pointer (it obviously is, since it's declared that way), but on the
    fact that "RAW" isn't a pointer.

    If you're unfamiliar with C, you know that "=" is an assignment
    operator, and that it causes the value of the right hand side to be
    copied to the object named by the left hand side. In this case, you
    might assume that the characters 'R', 'A', and 'W' (and the trailing
    '\0') are going to be copied -- but it ain't so.

    A string literal is an array of char. The trick is that, like any
    expression of array type, it's implicitly converted to a pointer to
    the array's first element in most contexts. This conversion doesn't
    happen when the array is the operand of a unary "&" or "sizeof"
    operator, or when it's a string literal use to initialize an array.

    (In case you were wondering, the last case doesn't apply here, since
    (a) it's an assignment, not an initializer, and (b) the object being
    initialized^H^H^H^H^H^H^H^H^H^H^H assigned to isn't an array.)

    So the assignment
    m = "RAW";
    copies, not the string "RAW", but the address of its first character,
    into m.

    The relationship between arrays and pointers in C can be confusing,
    and some features of the language almost seem to have been designed to
    maintain that confusion. The best cure I know of is to read and
    understand section 6 of the comp.lang.c FAQ, <http://www.c-faq.com/>.

    --
    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, Mar 12, 2008
    #11
    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. Guest
    Replies:
    4
    Views:
    477
    Guest
    Oct 13, 2004
  2. lovecreatesbeauty
    Replies:
    1
    Views:
    1,043
    Ian Collins
    May 9, 2006
  3. Tim Clacy
    Replies:
    8
    Views:
    393
    Tim Clacy
    May 30, 2006
  4. tropos
    Replies:
    6
    Views:
    438
    Gavin Deane
    Sep 21, 2006
  5. Pekka Järvinen
    Replies:
    2
    Views:
    664
    Richard Tobin
    Apr 29, 2008
Loading...

Share This Page