why this code does not compile?

Discussion in 'C Programming' started by Ninan Thomas, Aug 20, 2003.

  1. Ninan Thomas

    Ninan Thomas Guest

    #define MAX_PATH_NAME 100


    char audithome[MAX_PATH_NAME];

    audithome = getenv("AUDITHOME");



    this fails to compile giving an error
    "incompatible types in assignment"

    I am using gcc compiler on Solaris

    REgards

    Ninan
     
    Ninan Thomas, Aug 20, 2003
    #1
    1. Advertising

  2. "Allan Bruce" <> writes:

    > "Ninan Thomas" <> wrote in message
    > news:...
    > > #define MAX_PATH_NAME 100
    > >
    > >
    > > char audithome[MAX_PATH_NAME];
    > >
    > > audithome = getenv("AUDITHOME");
    > >
    > >
    > >
    > > this fails to compile giving an error
    > > "incompatible types in assignment"
    > >
    > > I am using gcc compiler on Solaris
    > >
    > > REgards
    > >
    > > Ninan

    >
    > getenv returns a char pointer, so you should have something like
    >
    >
    > #define MAX_PATH_NAME 100
    >
    > char *audithome = malloc(MAX_PATH_NAME);
    >
    > audithome = getenv("AUDITHOME");


    No! That would be a memory leak. After the `getenv' call, there's no
    way to access the memory returned by the `malloc' call.

    To the OP: It doesn't work because you cannot assign to an array.
    `getenv' returns a pointer to char, so the correct way to call it is:

    char *audithome = getenv("AUDITHOME");

    Note that `getenv' can return a null pointer. If it doesn't, the memory
    pointed to by `audithome' should not be modified. Furthermore, future calls
    to `getenv' may overwrite the same memory.

    Martin
     
    Martin Dickopp, Aug 20, 2003
    #2
    1. Advertising

  3. Ninan Thomas

    Guest

    Martin Dickopp <> broke the eternal silence and spoke thus:
    > char *audithome = getenv("AUDITHOME");


    So maybe

    char audithome[MAX_PATH];
    strncpy(audithome, getenv("AUDITHOME"), MAX_PATH - 1);

    ? (emphasis on '?', allowing for the coefficient of stupidity to kick in...)

    --
    Christopher Benson-Manica | Jumonji giri, for honour.
    ataru(at)cyberspace.org |
     
    , Aug 21, 2003
    #3
  4. Ninan Thomas

    Mike Wahler Guest

    Ninan Thomas <> wrote in message
    news:...
    > #define MAX_PATH_NAME 100
    >
    >
    > char audithome[MAX_PATH_NAME];
    >
    > audithome = getenv("AUDITHOME");


    Note that 'getenv()' is not a standard C function.
    But that's not the essence of the problem.

    >
    >
    >
    > this fails to compile giving an error
    > "incompatible types in assignment"


    Right. And in this case there is *no* 'compatible type'.
    IMO that message is misleading. It's not allowed to
    assign to an array.

    What type does that function 'getenv()' return?
    If it returns a pointer to a char, then use 'strcpy()'
    to write to the array (or perhaps simply assign the
    return value to a char*.) You should check the documentation
    to see if it might return NULL, in which case you don't
    want to dereference the returned value. Also, if using a
    'C89' compiler', and you don't provide a prototype, its
    return type will be assumed to be 'int'. If using a 'C99'
    compiler, calling a function whose prototype is not in scope is
    not allowed.

    -Mike
     
    Mike Wahler, Aug 21, 2003
    #4
  5. writes:

    > Martin Dickopp <> broke the eternal silence and spoke thus:
    > > char *audithome = getenv("AUDITHOME");

    >
    > So maybe
    >
    > char audithome[MAX_PATH];
    > strncpy(audithome, getenv("AUDITHOME"), MAX_PATH - 1);


    This fails (causes undefined behavior) if `getenv' returns a null pointer.
    Furthermore, `strncpy' does not write a '\0' character if its second
    argument is a string of the length indicated by the third argument or
    longer.

    char *const tmp = getenv ("AUDITHOME");
    if (tmp != 0)
    {
    char audithome [MAX_PATH];
    strncpy (audithome, tmp, sizeof audithome - 1);
    audithome [sizeof audithome - 1] = '\0';
    /* ... */
    }

    Martin
     
    Martin Dickopp, Aug 21, 2003
    #5
  6. Ninan Thomas

    Guest

    Martin Dickopp <> broke the eternal silence and spoke thus:

    > Furthermore, `strncpy' does not write a '\0' character if its second
    > argument is a string of the length indicated by the third argument or
    > longer.


    You know, I didn't believe you until I saw it in the man page myself... Why
    doesn't it?

    --
    Christopher Benson-Manica | Jumonji giri, for honour.
    ataru(at)cyberspace.org |
     
    , Aug 21, 2003
    #6
  7. Ninan Thomas

    Mike Wahler Guest

    Alex <> wrote in message
    news:jlT0b.795236$...
    > Mike Wahler <> wrote:
    >
    > > Ninan Thomas <> wrote in message
    > > news:...
    > >> #define MAX_PATH_NAME 100
    > >>
    > >>
    > >> char audithome[MAX_PATH_NAME];
    > >>
    > >> audithome = getenv("AUDITHOME");

    >
    > > Note that 'getenv()' is not a standard C function.
    > > But that's not the essence of the problem.

    >
    > Then it really shouldn't be defined in my copy of the standard :)


    Oops, sorry. I really put my foot in it, didn't I? :)

    -Mike
     
    Mike Wahler, Aug 21, 2003
    #7
  8. Ninan Thomas

    Guest

    Ben Pfaff <> broke the eternal silence and spoke thus:

    > * Using strncpy() into a large buffer can be very inefficient.
    > strncpy() always writes to every byte in the destination
    > buffer, which can waste a lot of time if the destination
    > buffer is much longer than the source string.


    Why is it implemented like this, if there is such a large performance penalty
    for writing to every byte?

    --
    Christopher Benson-Manica | Jumonji giri, for honour.
    ataru(at)cyberspace.org |
     
    , Aug 21, 2003
    #8
  9. Ninan Thomas

    CBFalconer Guest

    Ninan Thomas wrote:
    >
    > #define MAX_PATH_NAME 100
    >
    > char audithome[MAX_PATH_NAME];
    >
    > audithome = getenv("AUDITHOME");

    ^^^^^^^^^ ^---------see below for what this returns.
    this is not an lvalue.

    >
    > this fails to compile giving an error
    > "incompatible types in assignment"
    >
    > I am using gcc compiler on Solaris


    Which has nothing to do with it. From N869:

    7.20.4.4 The getenv function

    Synopsis
    [#1]
    #include <stdlib.h>
    char *getenv(const char *name);

    Description

    [#2] The getenv function searches an environment list,
    provided by the host environment, for a string that matches
    the string pointed to by name. The set of environment names
    and the method for altering the environment list are
    implementation-defined.

    [#3] The implementation shall behave as if no library
    function calls the getenv function.

    Returns

    [#4] The getenv function returns a pointer to a string
    associated with the matched list member. The string pointed
    to shall not be modified by the program, but may be
    overwritten by a subsequent call to the getenv function. If
    the specified name cannot be found, a null pointer is
    returned.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Aug 21, 2003
    #9
  10. Ninan Thomas

    Simon Biber Guest

    <> wrote:
    > Martin Dickopp <> spoke thus:
    > > Furthermore, `strncpy' does not write a '\0' character if
    > > its second argument is a string of the length indicated by
    > > the third argument or longer.

    >
    > You know, I didn't believe you until I saw it in the man page
    > myself... Why doesn't it?


    Despite its name, strncpy is not designed to produce strings, but
    rather to produce fixed width records, arrays of characters, in
    which the absence of a null character simply means that all
    available characters are used. This avoids wasting space for a
    redundant null character when the fixed width of the record is
    well-known.

    An example is the directory file format on some older operating
    systems, which has a fixed width record holding (say) 11 characters:
    A B C D E F G H J K L
    if all are filled, this represents the filename "ABCDEFGH.JKL".
    if not all are filled:
    A B C D E F \0 \0 D O C
    this represents "ABCDEF.DOC"
    H E L L O \0 \0 \0 C \0 \0
    this represents "HELLO.C"

    One way to fill such a record is with strncpy:

    char buf[11] = {0};
    strncpy(buf, "HELLO", 8);
    strncpy(buf + 8, "C", 3);

    This way you can use the whole 8+3 space for the filename without
    wasting space storing the dot or null terminators.

    On modern systems which support very long filenames, it is
    space-inefficient to use a fixed record width, which would
    waste much space storing zeroes for shorter filenames, so new
    variable length schemes have been introduced. However, fixed
    width records still exist and are quite useful in other areas.

    --
    Simon.
     
    Simon Biber, Aug 21, 2003
    #10
  11. Ninan Thomas

    Simon Biber Guest

    "CBFalconer" <> wrote:
    > Ninan Thomas wrote:
    > >
    > > #define MAX_PATH_NAME 100
    > >
    > > char audithome[MAX_PATH_NAME];
    > >
    > > audithome = getenv("AUDITHOME");

    > ^^^^^^^^^ ^---------see below for what this returns.
    > this is not an lvalue.


    It is an lvalue. It is not a modifiable lvalue.

    C99 6.3.2.1 Lvalues, arrays, and function designators
    1 An lvalue is an expression with an object type or an
    incomplete type other than void;53) if an lvalue does
    not designate an object when it is evaluated, the
    behavior is undefined. When an object is said to have
    a particular type, the type is specified by the lvalue
    used to designate the object. A modifiable lvalue is
    an lvalue that does not have array type, does not have
    an incomplete type, does not have a const-qualified
    type, and if it is a structure or union, does not have
    any member (including, recursively, any member or
    element of all contained aggregates or unions) with a
    const-qualified type.

    --
    Simon.
     
    Simon Biber, Aug 21, 2003
    #11
  12. Ninan Thomas

    Ninan Thomas Guest

    Hi all
    Thanks for all the replies to this question. I have a follow up question.

    I agree
    char *audithome = getenv("AUDITHOME");
    works.

    My question is if i define

    char audithome[MAX_PATH_NAME];

    and pass it as an argument to any function for example
    strcpy (char *, ------

    strcpy(audithome,
    it works. Here the argument is a pointer to char type???
    where as it does not work when the function returns a char * type?

    for example char *getenv(-------


    audithome = getenv("AUDITHOME")
    (Ninan Thomas) wrote in message news:<>...
    > #define MAX_PATH_NAME 100
    >
    >
    > char audithome[MAX_PATH_NAME];
    >
    > audithome = getenv("AUDITHOME");
    >
    >
    >
    > this fails to compile giving an error
    > "incompatible types in assignment"
    >
    > I am using gcc compiler on Solaris
    >
    > REgards
    >
    > Ninan
     
    Ninan Thomas, Aug 21, 2003
    #12
    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. Razvan
    Replies:
    7
    Views:
    1,228
    Babu Kalakrishnan
    Aug 24, 2004
  2. JavaMan
    Replies:
    1
    Views:
    355
    Lee Weiner
    Oct 30, 2004
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,077
    Smokey Grindel
    Dec 2, 2006
  4. Nagaraj
    Replies:
    1
    Views:
    892
    Lionel B
    Mar 1, 2007
  5. Paul Melis

    Why oh why does this NOT give a compile error?

    Paul Melis, Nov 5, 2007, in forum: C Programming
    Replies:
    13
    Views:
    530
    cr88192
    Nov 7, 2007
Loading...

Share This Page