strcpy warning

A

Ape Ricket

Hi. During my program's set-up phase where it reads in the arguments it
was invoked with, I programmed this:


if (strcmp(argv,"-G") ==0)
{
geom_scaling = ON;
if (i < argc-1)
strcpy(geom_string,argv[i+1]);
}


(
i is a loop counter,
geom_scaling has been declared as int,
ON has been #defined,
geom_string has been declared thus: char geom_string[64];
--the program is for my own use only, and a length of 64 is way way longer
than could ever make sense, hence the lack of error checking.
)

Could someone tell me whether to worry about the following compiler
warning, and how to fix it if needs be:

warning: type mismatch in implicit declaration for built-in function
`strcpy'

As you will have guessed, I'm a beginner. Thanks --Ape
 
T

Thomas Stegen

Ape said:
warning: type mismatch in implicit declaration for built-in function
`strcpy'

You are probably not including string.h.
Fix by adding
#include <string.h>
somewhere near the top of the file. (not necessary to put at top,
but usually that is what you do)

For a more in depth discussion on the issue read up on function
prototypes.
 
B

Barry Schwarz

Hi. During my program's set-up phase where it reads in the arguments it
was invoked with, I programmed this:


if (strcmp(argv,"-G") ==0)
{
geom_scaling = ON;
if (i < argc-1)


Consistent indenting will make your programs much easier to read.
strcpy(geom_string,argv[i+1]);
}


(
i is a loop counter,
geom_scaling has been declared as int,
ON has been #defined,
geom_string has been declared thus: char geom_string[64];
--the program is for my own use only, and a length of 64 is way way longer
than could ever make sense, hence the lack of error checking.
)

Could someone tell me whether to worry about the following compiler
warning, and how to fix it if needs be:

warning: type mismatch in implicit declaration for built-in function
`strcpy'

Did you #include string.h? Can you cut and paste a complete
compilable short program that demonstrates the problem.
As you will have guessed, I'm a beginner. Thanks --Ape



<<Remove the del for email>>
 
A

Ape Ricket

Barry Schwarz said:
if (strcmp(argv,"-G") ==0)
{
geom_scaling = ON;
if (i < argc-1)


Consistent indenting will make your programs much easier to read.
strcpy(geom_string,argv[i+1]);
}


hmmm, it looks to me as though each successive indentation has 4 extra
spaces. What's wrong with it?
Did you #include string.h?

Thanks Barry and others, I hadn't #included string.h, and doing so made
the warning go away. I find it odd that the program worked as
expected without the header file--where did gcc get the strcmp, strcpy and
strtok functions from, if I didn't #include the string library?

Is there a default version of strcpy that I was misusing, but not badly
enough to cause an error--just a compiler warning?

Another funny thing is that when I log in to the account where I do my
work, I sometimes get dropped into a server running UNIX, and sometimes
linux. The warnings on the version of gcc running on each are
different--linux doesn't care as much about the missing header file. And
neither compiler minded about strcmp, but strtok and strcpy both
engendered warnings. (As you can imagine this is a pain in the ass--if I
compile something on one architecture it won't run next time I log on and
get put on the other architecture. But this is OT and I apologise.)

Ape
 
A

Arthur J. O'Dwyer

Barry Schwarz said:
if (strcmp(argv,"-G") ==0)
{
geom_scaling = ON;
if (i < argc-1)


Consistent indenting will make your programs much easier to read.
strcpy(geom_string,argv[i+1]);
}


hmmm, it looks to me as though each successive indentation has 4 extra
spaces. What's wrong with it?


For some reason, I used to indent programs like this, back in my
Turbo C days:

if (foo)
{
int bar;
baz();
}
else
quux();

and I guess I must have found it readable at the time. But I now
find it a really ugly and illegible style, and don't remember how I
could possibly have found it logical. Your style is similarly
unidiomatic and thus hard-to-read for most of the regulars here
(including myself). I recommend switching. ;-)

if (foo) {
int bar;
baz();
}
else
quux();

is my preferred style now, for example. Note the key changes: braces
line up with their controlling statements, or are on the same line;
declarations line up with the statements that use them. [I also
make a rule of 2-space indentation for the bodies of control statements
without enclosing braces, like 'quux' above -- but that's not a
widespread usage, AFAIK.]

Thanks Barry and others, I hadn't #included string.h, and doing so made
the warning go away. I find it odd that the program worked as
expected without the header file--where did gcc get the strcmp, strcpy and
strtok functions from, if I didn't #include the string library?

Most compilers include the standard "libc" *library* whether or not
you #include the standard headers. So the linker knows where to find
these functions; it just doesn't know what type of parameters they
take, or what types they return. On your system, it turns out not to
matter to the machine code what the types are. This isn't true in
general, though. And gcc usually *won't* include the math "libm"
but *also* pass the said:
Is there a default version of strcpy that I was misusing, but not badly
enough to cause an error--just a compiler warning?

Sort of. Some compilers *would* give you an error; some linkers
would give you a linker error; but not gcc. See gnu.gcc.help for
more information on GCC in particular.
Another funny thing is that when I log in to the account where I do my
work, I sometimes get dropped into a server running UNIX, and sometimes
linux. The warnings on the version of gcc running on each are
different--linux doesn't care as much about the missing header file. And
neither compiler minded about strcmp, but strtok and strcpy both
engendered warnings.

strcmp() returns 'int', which is the default. 'strtok' and 'strcpy'
both return 'char *', which is not the default. C89 has undeclared
functions return 'int' by default, as if you had declared them

int strcmp();
int strtok();
int strcpy();

This is still wrong, of course, but not wrong enough in strcmp()'s
case to give you a warning about it.

HTH,
-Arthur
 
K

Kevin Goodsell

Ape said:
Barry Schwarz said:
if (strcmp(argv,"-G") ==0)
{
geom_scaling = ON;
if (i < argc-1)


Consistent indenting will make your programs much easier to read.

strcpy(geom_string,argv[i+1]);
}



hmmm, it looks to me as though each successive indentation has 4 extra
spaces. What's wrong with it?


The 'if' is indented relative to the geom_scaling assignment, even
though they are at the same "level".
Thanks Barry and others, I hadn't #included string.h, and doing so made
the warning go away. I find it odd that the program worked as
expected without the header file--where did gcc get the strcmp, strcpy and
strtok functions from, if I didn't #include the string library?

You don't #include libraries. You #include headers. Headers are very
different from libraries. Headers generally contain declarations - the
actual implementations are elsewhere. It's up to the linker to locate
and link against the correct libraries. For most compilers, there is a
set of default libraries it will check, and strcmp etc. are probably in
that default set.

The reason it sort of works without the #include is that versions of C
prior to C99 allowed implicit declaration of a function just by calling
it. This is usually a Bad Thing, since the implicit declaration may not
match the actual form of the function, and it causes the old calling
convention to be used (where arguments are promoted and no type checking
is done).
Is there a default version of strcpy that I was misusing, but not badly
enough to cause an error--just a compiler warning?

Most likely you were using the "real" strcpy. The incorrect (implicit)
declaration of it would make the behavior undefined. Appearing to work
correctly is one of the infinite possibilities that may result from
undefined behavior.
Another funny thing is that when I log in to the account where I do my
work, I sometimes get dropped into a server running UNIX, and sometimes
linux. The warnings on the version of gcc running on each are
different--linux doesn't care as much about the missing header file. And
neither compiler minded about strcmp, but strtok and strcpy both
engendered warnings.

It was probably smart enough to realize that the implicit declaration of
strcmp was correct (because it happens to return 'int', which is what
the return type defaults to in an implicit declaration). As for the
difference in diagnostics, it could be different versions of the
compiler or it could be using different default settings. I think gcc
has some config files that control default options.
(As you can imagine this is a pain in the ass--if I
compile something on one architecture it won't run next time I log on and
get put on the other architecture. But this is OT and I apologise.)

If that's the case you need to 1) write your code more portably and 2)
enable a more strict level of warnings and standard-compliance. Here are
the options I use for gcc. If you want, you can use this as a starting
point and find a good set of options for you.

-W -Wall -Wcast-align -Wwrite-strings -Wno-sign-compare
-Wno-unused-parameter -Wpointer-arith -Wundef -Wcast-qual
-Wunreachable-code -ansi -pedantic-errors

I just added the last 3 -W options, so I don't really know how they'll
work out yet. I might decide I don't like them.

-Kevin
 
K

Keith Thompson

Arthur J. O'Dwyer said:
if (foo) {
int bar;
baz();
}
else
quux();

is my preferred style now, for example. Note the key changes: braces
line up with their controlling statements, or are on the same line;
declarations line up with the statements that use them. [I also
make a rule of 2-space indentation for the bodies of control statements
without enclosing braces, like 'quux' above -- but that's not a
widespread usage, AFAIK.]

I *always* use braces on control statements, except in rare cases
where the whole thing is short enough to fit on one line. It's a
habit I picked up from Perl, which requires the braces, but I find it
useful; it looks more consistent, and makes maintenance easier when I
decide later that I want more than one statement.

The above would be:

if (foo) {
int bar;
baz();
}
else {
quux();
}

I'm not arguing that everyone must do this, it's just the style I like
to use.

In rare cases I might compress the layout to something like this:

if (foo) do_foo_stuff();
elsif (bar) do_bar_stuff();
elsif (baz) do_baz_stuff();
elsif (quux) do_quux_stuff();
else do_something_else();

but I often regret it later when I'm maintaining the code (which I
spend a lot more time on than writing it in the first place).
 
A

Arthur J. O'Dwyer

Arthur J. O'Dwyer said:
if (foo) {
int bar;
baz();
}
else
quux();
[I also make a rule of 2-space indentation for the bodies of
control statements without enclosing braces, like 'quux' above
-- but that's not a widespread usage, AFAIK.]

I *always* use braces on control statements, except in rare cases
where the whole thing is short enough to fit on one line. It's a
habit I picked up from Perl, which requires the braces, but I find it
useful [...]
else {
quux();
}

I'm not arguing that everyone must do this, it's just the style I like
to use.

I completely agree with you as far as the example I chose -- in a
real program, I would almost always put braces around the body of
an 'else' clause, especially in cases where the matching 'if' clause
had them. But I often write things like

int foo(void)
{
FILE *fp = fopen("bar", "r");

if (fp == NULL)
return -1;

...

In that case I find it more convenient *not* to add braces; and
if I'm not going to add braces, I find it more consistent *not* to
indent the body a full level. That way, whenever I'm maintaining
my own style of code, I can tell instantly if a closing brace is
missing: e.g., if I see

}
}

or
}
}

then I immediately *know* that there's a problem. Of course,
being able to rely on this "gimmick" in my own code means that I
have a harder time with other people's code than I might if I just
wrote awfully-formatted code to begin with. ;-)

In rare cases I might compress the layout to something like this:

if (foo) do_foo_stuff();
elsif (bar) do_bar_stuff();
^^^^^
Assuming, of course, that you were programming in CPerl. :)
but I often regret it later when I'm maintaining the code (which I
spend a lot more time on than writing it in the first place).

Yes; I used to do this, but then realized that it was going to
take up a lot of space on the page no matter how I indented it,
so I might as well be consistent.

-Arthur
 
K

Keith Thompson

Arthur J. O'Dwyer said:
I *always* use braces on control statements, except in rare cases
where the whole thing is short enough to fit on one line. It's a
habit I picked up from Perl, which requires the braces, but I find it
useful [...]
else {
quux();
}

I'm not arguing that everyone must do this, it's just the style I like
to use.

I completely agree with you as far as the example I chose -- in a
real program, I would almost always put braces around the body of
an 'else' clause, especially in cases where the matching 'if' clause
had them. But I often write things like

int foo(void)
{
FILE *fp = fopen("bar", "r");

if (fp == NULL)
return -1;

...

In that case I find it more convenient *not* to add braces; and
if I'm not going to add braces, I find it more consistent *not* to
indent the body a full level.
[...]

MMV (My Mileage Varies); I still prefer to use the braces in that
case. DGNED (De Gustibus Non Est Disputandum).

[...]
^^^^^
Assuming, of course, that you were programming in CPerl. :)

DOH (Dumb Oversight Here)!

I could claim that I use "#define elsif else if", but that would make
me look even more stupid. I meant "else if", of course.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,129
Messages
2,570,770
Members
47,329
Latest member
FidelRauch

Latest Threads

Top