Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Futures page man str[n]cat

89 réponses
Avatar
Marc Boyer
Voici donc ce qui devrait arriver dans les pages de man.
Par rapport à ce que nous avions proposé, les parties "WARNING"
et "BUG" ont été oublié, pour ne reprendre que la description
de ce qu'elles font, pas les mises en garde.




STRCAT(3) Linux Programmer's Manual STRCAT(3)

NAME
strcat, strncat - concatenate two strings

SYNOPSIS
#include <string.h>

char *strcat(char *dest, const char *src);

char *strncat(char *dest, const char *src, size_t n);

DESCRIPTION
The strcat() function appends the src string to the dest
string, overwriting the null character (`\0') at the end of
dest, and then adds a terminating null character. The
strings may not overlap, and the dest string must have
enough space for the result.

The strncat() function is similar, except that

* it will use at most n characters from src; and

* src does not need to be null terminated if it contains n
or more characters.

As with strcat(), the resulting string in dest is always
null terminated.

If src contains n or more characters, strcat() writes n+1
characters to dest (n from src plus the terminating null
character). Therefore, the size of dest must be at least
strlen(dest)+n+1.

A simple implementation of strncat() might be:

char*
strncat(char *dest, const char *src, size_t n)
{
size_t dest_len = strlen(dest);
int i;

for(i = 0 ; i < n && src[i] != '\0' ; i++)
dest[dest_len + i] = src[i];
dest[dest_len + i] = '\0';
return dest;
}

RETURN VALUE
The strcat() and strncat() functions return a pointer to the
resulting string dest.

CONFORMING TO
SVr4, 4.3BSD, C89, C99.

SEE ALSO
bcopy(3), memccpy(3), memcpy(3), strcpy(3), strncpy(3),
wcscat(3), wcsncat(3)




--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)

9 réponses

5 6 7 8 9
Avatar
Ael Rowan Terence
"Charlie Gordon" a écrit dans le message de
news:46a081b3$0$14114$
"Ael Rowan Terence" a écrit dans le message de news:
f7l37m$v07$



[...]
Car, même, dans le cas d'un compilateur desuet, ou mal configuré,
l'erreur


sera mentionnée.


Pourquoi tolérer que le compilateur soit mal configuré ? Bien d'autres


Je ne tiens pas à tolerer une telle abomination, bien au contraire.

[...]

Nonobstant, je suis d'accord avec toi, il vaut mieux disposer des
meilleurs
outils correctement parametrés. Mais est-ce, partout et tout le temps,
possible ?


Je prétends que oui.


C'est là où je ne suis pas aussi sûr que toi.

Je pense en particulier aux developpeurs sur de vieux OS plus maintenus
aujourd'hui, disposant que d'un vieux compilateur de l'époque sans mise à
jour possible.
Je pense aussi logiciels embarqués sur des micro-controlleurs qui ont eu
leur heure de gloire, mais aujourd'hui disparus.
Il me vient à l'idée le cas du Neuron de chez Echellon, cétait un
compilateur C avec des adaptations qui leur étaient propres.

Mais bon, j'avoue que j'avais plus de plaisir à converser avec toi, que de
m'arcbouter une sur une forme d'écriture completement archaique.


Avatar
Antoine Leca
En news:f7q2qs$f5v$, Ael Rowan Terence va escriure:
Charlie Gordon a écrit dans le message de
news:46a081b3$0$14114$
Ael Rowan Terence a écrit dans le message de news:
f7l37m$v07$
Nonobstant, je suis d'accord avec toi, il vaut mieux disposer des
meilleurs
outils correctement parametrés. Mais est-ce, partout et tout le
temps, possible ?


Je prétends que oui.


C'est là où je ne suis pas aussi sûr que toi.

Je pense en particulier aux developpeurs sur de vieux OS plus
maintenus aujourd'hui, disposant que d'un vieux compilateur de
l'époque sans mise à jour possible.


Ou bien le programme, ou plus exactement la partie encore en développement,
est portable (conforme à la norme), et ce n'est pas un argument, puisque tu
peux _aussi_ le compiler sur un compilateur « moderne », ou encore avec des
outils d'aide au développemnt (« génie logiciel ») type SPLint ou valgrind
ou que-sais-je-encore.
En fait c'est un des grands avantages apportés par la norme ANSI.


Ou bien le programme n'est pas portable, et effectivement tu es laissé à
toi-même, et à la merci des insuffisances du ou des compilateurs utilisés
initialement.

Et franchement, dans ces cas-là, dans la pratique que j'ai rencontrée,
l'insuffisance des avertissements sur les compilateurs désuets est un
problème mineur. Les bogues et autres incohérences des bibliothèques système
sont beaucoup plus pénibles.

Et bien sûr, pas de solution de mise à jour, puisque ces outils ne sont plus
maintenus...


Antoine



Avatar
Ael Rowan Terence
"Antoine Leca" a écrit dans le message de
news:f84vrt$cp7$

Ou bien le programme, ou plus exactement la partie encore en
développement,

est portable (conforme à la norme), et ce n'est pas un argument, puisque
tu

peux _aussi_ le compiler sur un compilateur « moderne », ou encore avec
des

outils d'aide au développemnt (« génie logiciel ») type SPLint ou valgrind
ou que-sais-je-encore.
En fait c'est un des grands avantages apportés par la norme ANSI.


Oui, effectivement, tu as parfaitement raison.



Ou bien le programme n'est pas portable, et effectivement tu es laissé à
toi-même, et à la merci des insuffisances du ou des compilateurs utilisés
initialement.



C'est dans cette eventualité que j'ai cité l'épouvantable Neuron de
Echellon.


[...]

Mais il peut-etre encore un cas plus général, qui pourrais déjouer les
compilateurs même modernes.

Si je definie :

#define TESTER( Test ) if ( Test )


Puis dans une fonction, j'appelle cette macro en tapant une coquille :

[...]

TESTER( n=0 )
{
/* faire quelquechose */
}

[...]

Les compilateurs "modernes" ou les outils d'aide au développement vont-ils
m'indiquer l'erreur ?

Avatar
Stéphane Zuckerman
On Tue, 24 Jul 2007, Ael Rowan Terence wrote:

Mais il peut-etre encore un cas plus général, qui pourrais déjouer les
compilateurs même modernes.

Si je definie :

#define TESTER( Test ) if ( Test )


Puis dans une fonction, j'appelle cette macro en tapant une coquille :

[...]

TESTER( n=0 )
{
/* faire quelquechose */
}

[...]

Les compilateurs "modernes" ou les outils d'aide au développement vont-ils
m'indiquer l'erreur ?


La réponse en images (qui me semble logique, d'ailleurs) :

:~/Programmation$ cat test.c
#include <stdio.h>

#define TESTER( test ) if ( test )

int
main(void)
{
int a = 1;
TESTER( a = 2 ) {
printf("a=2n");
}
return 0;
}
:~/Programmation$ gcc -Wall -O3 -o t test.c
test.c: In function 'main':
test.c:9: warning: suggest parentheses around assignment used as truth
value
:~/Programmation$

Comme prévu, une fois que le préprocesseur a fait son boulot, le « vrai »
boulot du compilateur commence.



--
"Je deteste les ordinateurs : ils font toujours ce que je dis, jamais ce
que je veux !"
"The obvious mathematical breakthrough would be development of an easy
way to factor large prime numbers." (Bill Gates, The Road Ahead)

Avatar
Vincent Lefevre
Dans l'article ,
Stéphane Zuckerman écrit:

La réponse en images (qui me semble logique, d'ailleurs) :

:~/Programmation$ cat test.c
#include <stdio.h>

#define TESTER( test ) if ( test )

int
main(void)
{
int a = 1;
TESTER( a = 2 ) {
printf("a=2n");
}
return 0;
}
:~/Programmation$ gcc -Wall -O3 -o t test.c
test.c: In function 'main':
test.c:9: warning: suggest parentheses around assignment used as truth
value
:~/Programmation$

Comme prévu, une fois que le préprocesseur a fait son boulot, le « vrai »
boulot du compilateur commence.


C'est juste parce que ton exemple est trop simple.

vin:~> cat tst.c
#include <stdio.h>

#define TESTER(T1,T2) if ((T1) && (T2))

int main (void)
{
int a = 1;
TESTER(a = 2, 1) {
printf("a=2n");
}
return 0;
}
vin:~> gcc -Wall -O3 tst.c
vin:~>

Pas de warning! C'est d'autant plus problématique si l'utilisateur
fait trop confiance à son compilo à propos des warnings et ne relit
pas son code.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

Avatar
Vincent Lefevre
Dans l'article <20070726132702$,
Vincent Lefevre <vincent+ écrit:

vin:~> cat tst.c
#include <stdio.h>

#define TESTER(T1,T2) if ((T1) && (T2))

int main (void)
{
int a = 1;
TESTER(a = 2, 1) {
printf("a=2n");
}
return 0;
}
vin:~> gcc -Wall -O3 tst.c
vin:~>

Pas de warning! C'est d'autant plus problématique si l'utilisateur
fait trop confiance à son compilo à propos des warnings et ne relit
pas son code.


D'ailleurs, je viens de voir qu'il y a un bug qui a été rapporté
sur un exemple similaire:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id2587

Mais je suppose que dans certains cas, l'utilisation du préprocesseur
rend les choses plus complexes, car il faut parfois ajouter des
paranthèses "au cas où", et il faudrait donc que l'analyse du code
tienne compte du source non préprocessé.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

Avatar
Ael Rowan Terence
"Vincent Lefevre" <vincent+ a écrit dans le message de
news:20070726132702$
Dans l'article ,

C'est juste parce que ton exemple est trop simple.

vin:~> cat tst.c
#include <stdio.h>

#define TESTER(T1,T2) if ((T1) && (T2))


Bravo, bien vu.
Je savais qu'il y avait un piège, mais c'est trop vieux, en fait d'écrire
"TESTER(T1) if ((T1))" suffit pour se faire berner.



int main (void)
{
int a = 1;
TESTER(a = 2, 1) {
printf("a=2n");
}
return 0;
}
vin:~> gcc -Wall -O3 tst.c
vin:~>

Pas de warning! C'est d'autant plus problématique si l'utilisateur
fait trop confiance à son compilo à propos des warnings et ne relit
pas son code.


Tu traduis parfaitement ma pensée: faire confiance, même à des outils
évolués, ne garantit pas contre toutes les coquilles.
Cela me conforte, pour l'instant, dans l'ecriture TESTER( 0==n ).

Avatar
Vincent Lefevre
Dans l'article <f8aa9h$tgk$,
Ael Rowan Terence écrit:

"Vincent Lefevre" <vincent+ a écrit dans le message de
news:20070726132702$
Dans l'article ,

C'est juste parce que ton exemple est trop simple.

vin:~> cat tst.c
#include <stdio.h>

#define TESTER(T1,T2) if ((T1) && (T2))


Bravo, bien vu.
Je savais qu'il y avait un piège, mais c'est trop vieux, en fait d'écrire
"TESTER(T1) if ((T1))" suffit pour se faire berner.


Sauf qu'écrire

#define TESTER(T1) if ((T1))

ce n'est pas très naturel, car les doubles parenthèses sont inutiles,
alors que dans mon exemple, elles sont indispensables pour que la macro
fonctionne avec certaines expressions, e.g. TESTER(a || b, c || d).

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)


Avatar
espie
A cote de ca, utiliser des macros pour ce genre de choses, c'est vraiment
chercher les emmerdes.

Ces jours-ci, a chaque fois que je vois une macro, j'essaie plutot de la
remplacer par un truc vaguement mieux foutu et mieux type... surtout avec
l'existence de fonctions inlines, c'est de moins en moins fin de cacher
des trucs dans le code (et je ne parle meme pas de l'autre solution, qui
consiste a passer en C++ pour beneficier du typage moins aleatoire et des
fonctions generiques).
5 6 7 8 9