You are not logged in.
Pages: 1
GCC is killing me..
#include <stdio.h>
//char *strncpy(char *s, const char *t, int n) don't work..
char *my_strncpy(char *s, const char *t, int n)
{
char *ret = s;
while (n-- && (*s++ = *t++))
;
if (n < 0)
*s = '\0';
return ret;
}
int main(void)
{
char name[1024];
//strncpy(name, "Tessio", 3);
my_strncpy(name, "Tessio", 3);
printf("%s\n", name);
return 0;
}
Can't I rewrite strncpy? Why? I am not even including "string.h" for god's sake...
Offline
Well, in fact you need the "-fno-builtin" flags to be able to use your strncpy.
Offline
But GCC sends no warnings and the code compile just fine.. How am I supposed to know all GCC's built-in functions?
Last edited by bera (2009-04-08 20:32:40)
Offline
Why do you even want to replace the existing implementation?
Offline
The prototype is
char *strncpy(char *s, const char *t, size_t n)
you get a error if don't change it and when #include <string.h> is present. (because declaration is diferent of the definition)
In this case, your strncpy is used instead of libc.
Offline
strncpy works very good. But you forget to null-terminate the string.
Warning: If you read the definition carefully, you will see that strncpy may not NULL terminate the resulting string! This is a surprise to many people, but it has a very good reason, and leads us to the idiomatic use of strncpy: ...
Offline
Why do you even want to replace the existing implementation?
It's a exercise of the book I'm learning C from (K&R)..
strncpy works very good. But you forget to null-terminate the string.
to NOT null-terminate the string.. right?
Last edited by bera (2009-04-09 00:46:08)
Offline
you get a error if don't change it and when #include <string.h> is present. (because declaration is diferent of the definition)
In this case, your strncpy is used instead of libc.
But my strncpy isn't been used reasonably. The compiled program don't work as expected..
Offline
What is the expected output? Please describe all chars.
Offline
What is the expected output? Please describe all chars.
Expected output: Tes
Real output: Tes%$%$%$(giberish) -> Its because gcc use another strncpy that do not null terminate the string..
The problem is that gcc used another strncpy instead of mine and sends no warnings..
Ps.: I compile with: gcc -Wall source.c
Last edited by bera (2009-04-09 12:00:18)
Offline
It's interesting, because running gcc3.4 here at work in cygwin produces the results you want:
$ cat test.c
#include <stdio.h>
char *strncpy(char *s, const char *t, size_t n)
{
char *ret = s;
while (n-- && (*s++ = *t++))
;
if (n < 0)
*s = '\0';
printf("USED!\n");
return ret;
}
int main(void)
{
char name[1024];
strncpy(name, "Tessio", 3);
printf("%s\n", name);
return 0;
}
$ gcc -otest -Wall test.c
$ ./test
USED!
Tes
$ gcc -v
Reading specs from /bin/../lib/gcc/i686-pc-cygwin/3.4.4/specs
Configured with: /usr/build/package/orig/test.respin/gcc-3.4.4-3/configure --verbose --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-languages=c,ada,c++,d,f77,pascal,java,objc --enable-nls --without-included-gettext --enable-version-specific-runtime-libs --without-x --enable-libgcj --disable-java-awt --with-system-zlib --enable-interpreter --disable-libgcj-debug --enable-threads=posix --enable-java-gc=boehm --disable-win32-registry --enable-sjlj-exceptions --enable-hash-synchronization --enable-libstdcxx-debug
Thread model: posix
gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
$
Offline
Interesting, hehe.
Your strncpy isn't used because, internally it calls to memcpy(). strncpy is a macro.
This is like printf, when printf is used the code call to puts()
Compile with -S to see the assembler code.
As say rip-rip use the flag -fno-builtin. (or declare your function as static, also this is a good practice)
/usr/include/bits/string.h
#define _HAVE_STRING_ARCH_strncpy 1
#define strncpy(dest, src, n) \
(__extension__ (__builtin_constant_p (src) \
? ((strlen (src) + 1 >= ((size_t) (n)) \
? (char *) memcpy ((char *) (dest), \
(__const char *) (src), n) \
: __strncpy_cg ((dest), (src), strlen (src) + 1, n))) \
: __strncpy_gg ((dest), (src), n)))
Remember that C is a very special lang that depends on the implementation.
You can see some interesting output with -E (stop at preprocess, to see the headers that are used)
Offline
This can help you http://c-faq.com/decl/namespace.html (comp.lang.c FAQ list · Question 1.29: How can I determine which identifiers are safe for me to use and which are reserved? )
Offline
It's interesting, because running gcc3.4 here at work in cygwin produces the results you want:
In slackware 12.2 it used to work as expected too.. o.O
My case:
[bera@preto ch05]$ cat ex07.c
#include <stdio.h>
char *strncpy(char *s, const char *t, int n)
{
char *ret = s;
while (n-- && (*s++ = *t++))
;
if (n < 0)
*s = '\0';
return ret;
}
char *strncat(char *s, const char *t, int n)
{
char *ret = s;
while (*s)
s++;
while (n-- && (*s++ = *t++))
;
if (n < 0)
*s = '\0';
return ret;
}
int strncmp(const char *s, const char *t, int n)
{
for ( ; n-- && *s == *t; s++, t++)
if (*s == '\0')
return 0;
if (n < 0)
return 0;
return *s - *t;
}
int main(void)
{
char nome[1024];
strncpy(nome, "Tessio", 3);
strncat(nome, "sioo", 3);
if(!strncmp(nome, "Tessio", 9))
printf("Ok: ");
else
printf("Bug: ");
printf("%s\n", nome);
return 0;
}
[bera@preto ch05]$ gcc -Wall ex07.c
[bera@preto ch05]$ ./a.out
Bug: Tessio
[bera@preto ch05]$ gcc -Wall -fno-builtin ex07.c
[bera@preto ch05]$ ./a.out
Ok: Tessio
The "problem" seems to be in the second line: "Using built-in specs."
[bera@preto ch05]$ gcc -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../configure --prefix=/usr --enable-shared --enable-languages=c,c++,fortran,objc,obj-c++,treelang --enable-threads=posix --mandir=/usr/share/man --infodir=/usr/share/info --enable-__cxa_atexit --disable-multilib --libdir=/usr/lib --libexecdir=/usr/lib --enable-clocale=gnu --disable-libstdcxx-pch --with-tune=generic
Thread model: posix
gcc version 4.3.3 (GCC)
[bera@preto ch05]$
Last edited by bera (2009-04-09 18:15:58)
Offline
This can help you http://c-faq.com/decl/namespace.html (comp.lang.c FAQ list · Question 1.29: How can I determine which identifiers are safe for me to use and which are reserved? )
Thanks a lot.. I reading this tight now..
Offline
Pages: 1