OVH Cloud OVH Cloud

Position sous-chaine

133 réponses
Avatar
Francois Cartegnie
Hello,

Je cherche un moyen de connaitre la position d'une occurence dans une chaine


J'ai essayé :
temp = strstr(bufferspace, "truc");
taille = temp-bufferspace;
Ne fonctionne pas car temp peut prendre la valeur NULL et donc le
compilateur refuse.

Etant dans l'espace noyau, je n'ai accès qu'a des fonctions sortant un
pointeur, et non la position.

Cordialement,

10 réponses

Avatar
Antoine Leca
Gabriel Dos Reis écrivit:
"Antoine Leca" writes:


T'es pas obligé de citer mon "adresse" ! ;-)

Il y a trois types, parce qu'il y a trois besoins (stocker un
caractère, stocker un entier signé de petite magnitude, stocker un
entier non signé de petite magnitude et assurer ainsi des calculs
vérifiables).


et tripafouiller de la mémoire brute.


Oui.

C classic, utilisait char.


Voui.

Le comité a introduit void* à la place,


Nan. je parlais des types entiers sur un byte, pas des pointeurs.
void* est une autre bestiole, qui vient s'ajouter aux _trois_ types
pointeurs vers caractères dérivés des trois types caractères.
On a donc _quatre_ types pointeurs, pas moins, qui ont eux
aussi les règles d'identité de représentation etc. que dénonce
Laurent. Quel est le besoin, me direz-vous ? Bin en fait, la
meilleure explication que j'ai trouvé, c'est que les types pointeurs
vers caractères sont là pour représenter, en fait, les tableaux
de chacun des trois types entiers, tandis que void* représente
le type pointeur anonyme, compatible avec tout et jamais
déréférençable.
Utiliser unsigned char* pour cet usage: c'était probablement une
possibilité, elle n'a pas été retenue, je n'en sais pas plus,
maintenant faut faire avec.

mais n'a pas étandu les règles
d'arithmétique de pointeur. Bien sûr, on peur caster void* and char*
et faire l'arithmétique, mais il aurait été plus simple d'avoir
l'arithmétique directement une fois que le pas a été franchis.


Hmmm, mon idée c'est que le comité a jugé plus important de garder
la propriété "non déréférençable" à la possibilité de faire de
l'arithmétique de pointeurs sans transtypages laids et disgracieux
(et comme en plus, on a const qui ne veut pas vraiment dire const
mais readonly dans le contexte, cela ne fait qu'ajouter à la confusion).

En plus, comme tu le faisais remarquer, les anciens codes
utilisaient char* (à toutes les sauces), donc de toutes manières
il fallait les modifier (en unsigned char*), donc void* a au moins le
mérite d'être plus court dans ce contexte (et vu le nombre de fois où
je me gourre en tapant unisgned, peut-être qu'il n'avait pas si tord...)


Antoine


Avatar
Gabriel Dos Reis
--=-=- Content-Type: text/plain; charset=iso-8859-15
Content-Transfer-Encoding: quoted-printable

"Antoine Leca" writes:

| Vincent Lefevre écrivit:
| > Dans l'article ,
| > Emmanuel Delahaye écrit:
| >
| >> Je ne vois pas écrit qu'il faille un diagnostic et arréter la
| >> compilation si un opérande est signé et l'autre non. Mais toi qui a
| >> une meilleure vue que moi, tu va me dire où c'est écrit.
| >
| > En tout cas, c'est au moins du comportement indéfini.
|
| Non non, cela demande un diagnostic, il y a violation de contrainte.
| Cela étant, violation de contrainte ne signifie pas erreur (en C),

--=-=- Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit


la règle est la même en C++. On émet un diagnostique et on fait ce
que tu veux après. Je n'ai jamais réussi à identifier clairement si
reformater le disque dur peut compter pour diagnostique ou pas. Je
crois qu'allummer le led vert pendant deux secondes est acceptable.

--=-=- Content-Type: text/plain; charset=iso-8859-15
Content-Transfer-Encoding: quoted-printable


| le compilateur peut accepter de générer le code. Il lui est juste
| requis de signaler que ce n'est pas bien^H^H^H^Hportable.

--=-=- Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit


mais rien n'oblige que le code généré fasse quelque chose de
sensé.

-- Gaby

--=-=-=--
Avatar
Gabriel Dos Reis
Laurent Deniau writes:

| Gabriel Dos Reis wrote:
| > "Antoine Leca" writes:
| > [...]
| > | > dans la pratique, je ne vois pas comment c'est possible a moins
| > de le
| > | > decreter (sans fondement) histoire de faire ch... Pour moi char doit
| > | > etre compatible avec un des deux types signed char ou unsigned char
| > | > mais c'est implementation defined donc pas portable.
| > | | Je pense que tu n'as pas compris à quoi sert d'avoir _trois_
| > types.
| > | | Il y a trois types, parce qu'il y a trois besoins (stocker un
| > caractère,
| > | stocker un entier signé de petite magnitude, stocker un entier
| > | non signé de petite magnitude et assurer ainsi des calculs vérifiables).
| > et tripafouiller de la mémoire brute. C classic, utilisait char. Le
| > comité a introduit void* à la place, mais n'a pas étandu les règles
| > d'arithmétique de pointeur. Bien sûr, on peur caster void* and char*
| > et faire l'arithmétique, mais il aurait été plus simple d'avoir
| > l'arithmétique directement une fois que le pas a été franchis.
|
| Par forcement (en tout cas c'est pas mon avis).

Pas forcément pour quoi exactement ?

Ce qui m'intéresse en premier lieu c'est de pouvoir implémenter
quelque chose comme my_memcpy(void*, const void*, int).

| On peut utiliser void*
| pour faire de l'ADT, et authoriser une arithmetique dessus peut-etre
| dangereux pour qui manipulerait par inadvertance des pointeurs de ce
| type.

L'arithmétique sur void* est certainement moins dangeureuse que la
conversion _implicite_ de void* en n'importe quel T*, où T est un
type d'objet. L'arithmétique n'est pas une opération implicite, alors
que la conversion l'est.

comment imnplémenter my_qsort() en faisant de l'arithmétique sur void* ?

[...]

| je pense qu'il existe beaucoup de vieux codes moins "proteger" (pas de
| struct, pas de const) qui pourrait avoir ce type de probleme si on
| autorisait l'arithmetique sur void*.

s'ils existent, ces problèmes sont imaginaires.

-- Gaby
Avatar
Antoine Leca
Laurent Deniau écrivit:
Typiquement mon ADT en C ressemble a ca:


Heu, excusez la question du Neu-neu, ADT, que es aco?


#define D_ADT struct { void const * const _; } *


Dangereux cela, tu définis un structure anonyme (différente)
à chaque invocation de la macro; c'est peut-être ce que tu
veux, mais d'autres pourrait facilement se méprendre...


typedef D_ADT array;
typedef D_ADT list;

(le define est dans un header a part) independament des const, ca
m'embeterait que l'utilisateur puisse changer la valeur de _ sans le
faire expres ne sachant pas vers quoi il pointe.


Si le méchant a déjà trouvé que D_ADT est un pointeur vers une
structure dont un membre s'appelle _ et est un pointeur (ouf), il ne
va pas s'arrêter en si bon chemin, et va te faire un transtypage !
Sans compter qu'avec les const, tu appelles à grand cris cette
« solution »...


je pense qu'il existe beaucoup de vieux codes moins "proteger" (pas
de struct, pas de const) qui pourrait avoir ce type de probleme si on
autorisait l'arithmetique sur void*.


Peut-être; cela étant, si C était un langage « sûr », cela se saurait...


Antoine

Avatar
Gabriel Dos Reis
Vincent Lefevre <vincent+ writes:

[...]

| > Non. Le comportement est parfaitement défini (6.5.6p9).
|
| Je ne suis pas d'accord. On est dans un cas non défini par la norme.

Regarde la définition de "undefined behaviour".

| Par exemple, quel comportement devrait-on avoir pour
|
| (int*) p - (char*) q
|
| avec sizeof(int) == 4?

La norme definit que c'est une violation de constraintes.

-- Gaby
Avatar
Vincent Lefevre
Dans l'article <bh7tch$obm$,
Antoine Leca écrit:

Il y a trois types, parce qu'il y a trois besoins (stocker un caractère,
stocker un entier signé de petite magnitude, stocker un entier
non signé de petite magnitude et assurer ainsi des calculs vérifiables).


Mais on n'a aucune garantie qu'on puisse stocker un caractère (au
sens courant) dans un char. Aujourd'hui, si c'était à refaire, char
ne devrait plus exister.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/> - 100%
validated (X)HTML - Acorn Risc PC, Yellow Pig 17, Championnat International
des Jeux Mathématiques et Logiques, TETRHEX, etc.
Work: CR INRIA - computer arithmetic / SPACES project at LORIA

Avatar
Gabriel Dos Reis
"Antoine Leca" writes:

| Gabriel Dos Reis écrivit:
| > "Antoine Leca" writes:
|
| T'es pas obligé de citer mon "adresse" ! ;-)

cela fait bientôt un mois qu'elle m'intrigue :-)

| >> Il y a trois types, parce qu'il y a trois besoins (stocker un
| >> caractère, stocker un entier signé de petite magnitude, stocker un
| >> entier non signé de petite magnitude et assurer ainsi des calculs
| >> vérifiables).
| >
| > et tripafouiller de la mémoire brute.
|
| Oui.
|
| > C classic, utilisait char.
|
| Voui.
|
| > Le comité a introduit void* à la place,
|
| Nan. je parlais des types entiers sur un byte, pas des pointeurs.

je comprends bien cela. Cependant, le point est que si char est une
unité officielle de mesure de la mémoire brute, alors char* peut être
interpèté comme un pointeur sur de la mémoire brute, or une telle
entité est communément représenté par void*. Voilà le lien que je
faisais dans mon message.

| void* est une autre bestiole, qui vient s'ajouter aux _trois_ types
| pointeurs vers caractères dérivés des trois types caractères.
| On a donc _quatre_ types pointeurs, pas moins, qui ont eux
| aussi les règles d'identité de représentation etc. que dénonce
| Laurent. Quel est le besoin, me direz-vous ? Bin en fait, la
| meilleure explication que j'ai trouvé, c'est que les types pointeurs
| vers caractères sont là pour représenter, en fait, les tableaux
| de chacun des trois types entiers, tandis que void* représente
| le type pointeur anonyme, compatible avec tout et jamais
| déréférençable.

en realité, à part la déréférençabilité (ça existe ça ?), void* a les
mêmes caractéristiqques que char*, et aucun autre T* (T différent de
charactère) ne jouit de la même propriété. En fait void* n'est pas
vriament anonyme.

| Utiliser unsigned char* pour cet usage: c'était probablement une
| possibilité, elle n'a pas été retenue, je n'en sais pas plus,
| maintenant faut faire avec.
|
| > mais n'a pas étandu les règles
| > d'arithmétique de pointeur. Bien sûr, on peur caster void* and char*
| > et faire l'arithmétique, mais il aurait été plus simple d'avoir
| > l'arithmétique directement une fois que le pas a été franchis.
|
| Hmmm, mon idée c'est que le comité a jugé plus important de garder
| la propriété "non déréférençable" à la possibilité de faire de
| l'arithmétique de pointeurs sans transtypages laids et disgracieux

mouais, mais alors le même argument s'applique pour la conversion
implicite void* -> T* pour n'importe quel T, type d'objet. Cette
conversion implicite est beaucoup plus pernicieuse que l'arithmétique.
BS en raconte un rayon sur comment void* a été transmoglifié par le
comité.

-- Gaby
Avatar
Erwan David
Vincent Lefevre <vincent+ écrivait :

Dans l'article <bh7tch$obm$,
Antoine Leca écrit:

Il y a trois types, parce qu'il y a trois besoins (stocker un caractère,
stocker un entier signé de petite magnitude, stocker un entier
non signé de petite magnitude et assurer ainsi des calculs vérifiables).


Mais on n'a aucune garantie qu'on puisse stocker un caractère (au
sens courant) dans un char. Aujourd'hui, si c'était à refaire, char
ne devrait plus exister.


Ou plutôt s'appeler byte ou short short int...

--
Monde de merde


Avatar
Vincent Lefevre
Dans l'article ,
Gabriel Dos Reis écrit:

mouais, mais alors le même argument s'applique pour la conversion
implicite void* -> T* pour n'importe quel T, type d'objet. Cette
conversion implicite est beaucoup plus pernicieuse que l'arithmétique.


Pourquoi? Le programmeur n'est-il pas censé connaître son langage et
programmer en conséquence?

--
Vincent Lefèvre - Web: <http://www.vinc17.org/> - 100%
validated (X)HTML - Acorn Risc PC, Yellow Pig 17, Championnat International
des Jeux Mathématiques et Logiques, TETRHEX, etc.
Work: CR INRIA - computer arithmetic / SPACES project at LORIA

Avatar
Antoine Leca
Vincent Lefevre écrivit:
Oui, mais une violation de contrainte, c'est un cas particulier
de comportement indéfini (avec des choses en plus), non?


Pour moi, ce sont deux notions orthogonales.
Relis 2. avec mon point de vue, tu me diras ce que tu en penses.


Antoine