This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
gcc strcpy pseudo bug or detail
- From: "Mauricio Labra" <mauricio dot labra at construmart dot cl>
- To: <bug-gcc at gnu dot org>
- Cc: <gcc at gcc dot gnu dot org>
- Date: Thu, 17 Oct 2002 11:21:52 -0400
- Subject: gcc strcpy pseudo bug or detail
Hi, sorry for my english...
I have a RH 7.2 and detect this detail (in C example):
# rpm -qi gcc
Name : gcc Relocations: (not relocateable)
Version : 2.96 Vendor: Red Hat, Inc.
Release : 98 Build Date: mar 04 sep 2001 14:10:42 CLT
Install date: mar 09 jul 2002 07:53:37 CLT Build Host: stripples.devel.redhat.com
Group : Development/Languages Source RPM: gcc-2.96-98.src.rpm
Size : 8376529 License: GPL
Packager : Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla>
URL : http://gcc.gnu.org
Summary : Various compilers (C, C++, Objective-C, Java, ...)
Description :
The gcc package contains the GNU Compiler Collection: cc and gcc. You'll need
this package in order to compile C/C++ code.
Source sample program x.c :
#include <stdio.h>
#include <string.h>
int main()
{
char tmp[80];
strcpy(tmp,msg());
puts(tmp);
return(0);
}
char *msg()
{
return("Mensaje de prueba");
}
This sample have a warnings...
# gcc -O3 -Wall x.c
x.c: In function `main':
x.c:9: warning: implicit declaration of function `msg'
x.c:9: warning: passing arg 1 of `strlen' makes pointer from integer without a cast
x.c:9: warning: passing arg 1 of `strlen' makes pointer from integer without a cast
x.c:9: warning: passing arg 1 of `strlen' makes pointer from integer without a cast
x.c:9: warning: passing arg 2 of `memcpy' makes pointer from integer without a cast
x.c:9: warning: passing arg 2 of `strcpy' makes pointer from integer without a cast
x.c: At top level:
x.c:15: warning: type mismatch with previous implicit declaration
x.c:9: warning: previous implicit declaration of `msg'
x.c:15: warning: `msg' was previously implicitly declared to return `int'
Whats are the warnings "makes pointer from integer without a cast" of strlen or memcpy functions?
I don't use this functions !
#gcc -O3 -Wall -E x.c
...
...
...
int main()
{
char tmp[80];
(__extension__ (__builtin_constant_p (msg()) ? (((size_t)(const void *)((msg()) + 1) - (size_t)(const
void *)(msg()) == 1) && strlen (msg()) + 1 <= 8 ? __strcpy_small (tmp, __extension__ (((__const unsigned cha
r *) (__const char *) (msg()))[0 + 1] << 8 | ((__const unsigned char *) (__const char *) (msg()))[0]), __exte
nsion__ (((__const unsigned char *) (__const char *) (msg()))[4 + 1] << 8 | ((__const unsigned char *) (__con
st char *) (msg()))[4]), __extension__ (((((__const unsigned char *) (__const char *) (msg()))[0 + 3] << 8 |
((__const unsigned char *) (__const char *) (msg()))[0 + 2]) << 8 | ((__const unsigned char *) (__const char
*) (msg()))[0 + 1]) << 8 | ((__const unsigned char *) (__const char *) (msg()))[0]), __extension__ (((((__con
st unsigned char *) (__const char *) (msg()))[4 + 3] << 8 | ((__const unsigned char *) (__const char *) (msg(
)))[4 + 2]) << 8 | ((__const unsigned char *) (__const char *) (msg()))[4 + 1]) << 8 | ((__const unsigned cha
r *) (__const char *) (msg()))[4]), strlen (msg()) + 1) : (char *) memcpy (tmp, msg(), strlen (msg()) + 1)) :
strcpy (tmp, msg())));
puts(tmp);
return(0);
}
char *msg()
{
return("Mensaje de prueba");
}
Aha!! Why gcc transform a simple strcpy in this macro code ?
The strcpy with function argument are dangerous...!!!
this execute many times the function !!!
Solution :
#include <stdio.h>
#include <string.h>
char *msg()
{
return("Mensaje de prueba");
}
int main()
{
char tmp[80];
char *aux;
aux=msg();
strcpy(tmp,aux);
// Esto es mas simple
// memcpy(tmp,msg(),strlen(msg())+1);
puts(tmp);
return(0);
}
#gcc -O3 -Wall x.c
No warnings.
#gcc -O3 -Wall -E x.c
...
...
char *msg()
{
return("Mensaje de prueba");
}
int main()
{
char tmp[80];
char *aux;
aux=msg();
(__extension__ (__builtin_constant_p (aux) ? (((size_t)(const void *)((aux) + 1) - (size_t)(const void *)(aux) == 1) && strlen (aux) + 1 <= 8 ? __strcpy_small (tmp, __extension__ (((__const unsigned char *) (__const char *) (aux))[0 + 1] << 8 | ((__const unsigned char *) (__const char *) (aux))[0]), __extension__ (((__const unsigned char *) (__const char *) (aux))[4 + 1] << 8 | ((__const unsigned char *) (__const char *) (aux))[4]), __extension__ (((((__const unsigned char *) (__const char *) (aux))[0 + 3] << 8 | ((__const unsigned char *) (__const char *) (aux))[0 + 2]) << 8 | ((__const unsigned char *) (__const char *) (aux))[0 + 1]) << 8 | ((__const unsigned char *) (__const char *) (aux))[0]), __extension__ (((((__const unsigned char *) (__const char *) (aux))[4 + 3] << 8 | ((__const unsigned char *) (__const char *) (aux))[4 + 2]) << 8 | ((__const unsigned char *) (__const char *) (aux))[4 + 1]) << 8 | ((__const unsigned char *) (__const char *) (aux))[4]), strlen (aux) + 1) : (char *) memcpy (tmp, aux, strlen (aux) + 1)) : strcpy (tmp, aux)));
puts(tmp);
return(0);
}
Please, tell me what is this and/or how to skip this macro...
and what other functions use this kind of macro control ?
I use string functions very well, and don't need extra code.
Thanxz.