Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > why this code does not compile?

Reply
Thread Tools

why this code does not compile?

 
 
Ninan Thomas
Guest
Posts: n/a
 
      08-20-2003
#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
 
Reply With Quote
 
 
 
 
Martin Dickopp
Guest
Posts: n/a
 
      08-20-2003
"Allan Bruce" <(E-Mail Removed)> writes:

> "Ninan Thomas" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) om...
> > #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
 
Reply With Quote
 
 
 
 
ataru@nospam.cyberspace.org
Guest
Posts: n/a
 
      08-20-2003
Martin Dickopp <(E-Mail Removed)> 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 |
 
Reply With Quote
 
Mike Wahler
Guest
Posts: n/a
 
      08-20-2003

Ninan Thomas <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> #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



 
Reply With Quote
 
Martin Dickopp
Guest
Posts: n/a
 
      08-20-2003
http://www.velocityreviews.com/forums/(E-Mail Removed) writes:

> Martin Dickopp <(E-Mail Removed)> 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
 
Reply With Quote
 
ataru@nospam.cyberspace.org
Guest
Posts: n/a
 
      08-21-2003
Martin Dickopp <(E-Mail Removed)> 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 |
 
Reply With Quote
 
Mike Wahler
Guest
Posts: n/a
 
      08-21-2003

Alex <(E-Mail Removed)> wrote in message
news:jlT0b.795236$(E-Mail Removed). ca...
> Mike Wahler <(E-Mail Removed)> wrote:
>
> > Ninan Thomas <(E-Mail Removed)> wrote in message
> > news:(E-Mail Removed) om...
> >> #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


 
Reply With Quote
 
ataru@nospam.cyberspace.org
Guest
Posts: n/a
 
      08-21-2003
Ben Pfaff <(E-Mail Removed)> 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 |
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      08-21-2003
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 ((E-Mail Removed)) ((E-Mail Removed))
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!


 
Reply With Quote
 
Simon Biber
Guest
Posts: n/a
 
      08-21-2003
<(E-Mail Removed)> wrote:
> Martin Dickopp <(E-Mail Removed)> 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", ;
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.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Why :: ? Why not : ? Why not . ? <- less clutter ?!? Skybuck Flying C++ 16 08-25-2007 09:48 PM
why why why why why Mr. SweatyFinger ASP .Net 4 12-21-2006 01:15 PM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
why why why does function not work Horace Nunley ASP .Net 1 09-27-2006 09:52 PM
Why does this (very simple piece of) code does not work? jblazi Python 5 08-16-2004 01:30 PM



Advertisments