Une rectification s'impose de mon côté : le diff entre les deux binaires était foiré, il n'y a aucune différence (à ma grande surprise, d'ailleurs) entre les deux binaires autre que les noms des fichiers.
Dans un cas réel avec une variable, je pense que le code généré serait différent, je maintiens ce que je pense sur la sémantique, mais effectivement sur un code basique le code généré en -O2 est strictement identique. Désolé !
Il n'y aucune différence effectivement, comme je l'ai dis, puisque nécessairement le compilateur ne saura pas optimiser.
Par contre, il y a des différences si tu fais ceci :
Dans le second cas, le compilateur ne passera même pas dans les boucles, alors qu'il passera dans le premier cas.
Tu peux également rajouter des calculs qui n'ont pas d'influence sur le reste, gcc l'optimise également (à ma grande surprise, c'était plutôt chiant pour des benchmarks. J'ai découvert ça il y a quelques jours) :
void bar() {
int a[100000];
int b[100000];
for(int i = 0; i < 100000; i++)
a[i] = i;
for(int i = 0; i < 100000; i++)
b[i] = i;
for(int i = 0; i < 100000; i++) {
for(int j = 0; j < 100000; j++) {
a[i] += j*b[i];
}
}
}
C'était grosso-modo le code que je voulais utiliser pour avoir un tant CPU conséquent. Tellement bien optimisé que malgré la taille et malgré le nombre de boucle imbriqué, j'avais toujours un temps de quelques millisecondes. Il ne passaient effectivement pas dedans parce qu'aucune des variables n'était utilisé ailleurs que localement et n'avait aucune incidence sur des variables locales dont la valeur étaient utilisées ailleurs.
Dans le second cas, le compilateur ne passera même pas dans les boucles, alors qu'il passera dans le premier cas.
Ton code ne compile pas, donc je suppose que tu n'as pas testé. Il aurait peut-être fallu parce que chez moi, on ne passe dans les boucles dans aucun cas.
Génération des fichiers asm a.s et b.s et comparaison (ils sont identiques à part pour le nom du fichier .c d'origine) :
Et quand je dis qu'on a pas le droit d'utiliser de lib, en gros je veux dire qu'aucun fichier ne doit être inclus dans les *.c sauf nos propre fichier. (stdlib.h et stdio.h par exemple ne doivent pas être inclus) Enfin je crois...
Tiens, à ce propos, j'ai dû révoquer plusieurs fois un contributeur insistant qui retirait cette inclusion d'un exemple de Wikipédia. Et il confondait bibliothèque et inclusion. Enfin bref, s'il était possible de dissiper les inexactitudes à ce sujet, ce serait cool.
En effet, à moins d'écrire vraiment salement, il faut tinclure <unistd.h> qui contient le prototype de la fonction write : ssize_twrite(intfildes,constvoid*buf,size_tnbyte);
Quant à write, ça fait partie des appels système classiques de Unix. Typiquement, c'est implémenté en passant par la libc, qui contient une fonction write appelable en C, et qui elle-même n'est qu'un stub qui fait l'appel système proprement dit. Enfin, pour le détail exact, voir votre système ( http://fxr.watson.org/fxr/source/kern/syscalls.master , http://syscalls.kernelgrok.com/ , etc.)
Et quand je dis qu'on a pas le droit d'utiliser de lib, en gros je veux dire qu'aucun fichier ne doit être inclus dans les *.c sauf nos propre fichier. (stdlib.h et stdio.h par exemple ne doivent pas être inclus) Enfin je crois...
Ah j'avais pas lu ça, mais en tout cas si à l'école tu as le droit d'inclure tous les .h du monde, tant que tu n'utilises pas les fonctions temporairement interdite.
Ah d'accord, je ne savais pas, je savais juste qu'on avait pas le droit d'utiliser des fonction comme printf ou des boucles comme for pendant la piscine. Merci pour l'info
PS : Désolé si j'ai réveiller un vieux post qui a mal tourner, ce n'était pas mon intention. Mais a ce que je vois, ça s'arrange
Oui certaines parties (beaucoup) de la norme d'epitech appliquee sur le C est stupide et contre productif (comme l'interdiction de for, switch, break entre autre bien casse couille) mais certaines parties on un interet ( comme les 25 lignes de fonctions ) je n'ai pas d'autre exemple en tete la n'etant plus confronter a cette norme depuis un certains temps,
Dans le cas du for et while, j'ai personnellement toujours preferer un for ( non pas pour une meilleur performance ou d'optimisation) mais parce qu'elle permet de reduire le code et de le rendre plus lisible en declarant/initialisant directement les variables necessaires a cette boucle.
Je crois qu'en fait, on se fout du contenu de la norme Epitech, tant qu'elle ne sort pas d'Epitech. J'ai vu un Epitech au boulot, il ne code pas avec ces règles, donc, en généralisant, pour ceux qui sont sortis de l'école, c'est bon. Pour ceux qui y sont, je pense qu'on attend d'eux de savoir réécrire un code selon une autre norme, donc ils n'ont pas à nous emmerder avec sur un forum publique. Notez que ça ne concerne pas que la norme de la piscine Epitech. Celui qui vient ici en se plaignant que les codes ne respectent pas les règles MISRA, je me ferai un plaisir de leur expliquer pourquoi elles n'ont pas lieu d'être ici.
Et, concernant les compilo, ceux qui ont subit autant de dev que GCC gèrent les dépendances entre instructions, les accès mémoires, etc... Du coup, il vaut mieux coder en pensant à la sémentique qu'à un code pour un humain plutôt qu'à l'efficacité du code, ce second point n'étant humainement estimable que pour des compilations naïves (je parle bien ici des optimisations genre "réutiliser une variable plutôt qu'en déclarer une deuxième, faire un for ou un while... La complexité algorithmique, elle, doit rester en tête des préoccupations du développeur, en la nuance par l'importance du segment de code dans le programme).
Nathalya >> Oui on s'en fou clairement mais tout se debat a ete lancer a cause justement de cette norme et de la pseudo interdiction de for (norme qui par ailleurs n'est valable que pendant la premiere annee [moitie])
Citation : ledenomejojo
Ah d'accord, je ne savais pas, je savais juste qu'on avait pas le droit d'utiliser des fonction comme printf ou des boucles comme for pendant la piscine. Merci pour l'info
interdit tant que tu ne les a pas recoder ( juste apres la piscine )
Je crois qu'en fait, on se fout du contenu de la norme Epitech, tant qu'elle ne sort pas d'Epitech.
Oui. Plus généralement, quel que soit l'endroit où l'on soumet du code, il y a des conventions, et si on ne les suit pas, on se fait rabrouer. Sur un forum Internet, les conventions sont assez souples, mais tout de même pas suffisamment souples pour être compatibles avec les conventions destinées aux primo-débutants d'Epitech.
À chaque public sa convention, et celui qui ne s'y plie pas n'a pas à s'étonner de se faire rabrouer, que ce soit ici où dans son école.
Ce sont les soeurs, les cousines des fonctions "simples", par exemple, strncpy est pratiquement identique à strcpy, sauf que strncpy ne copie qu'un certain nombre de caractères. Au lieu de copier toute la chaine source dans la chaine de destination (comportement de strcpy), on peut demander à strncpy de ne copier que <math>\(n\)</math> caractères.
par exemple, strncpy est pratiquement identique à strcpy, sauf que strncpy ne copie qu'un certain nombre de caractères. Au lieu de copier toute la chaine source dans la chaine de destination (comportement de strcpy), on peut demander à strncpy de ne copier que <math>\(n\)</math> caractères.
En fait la fonction strncpy est très piègeuse et sémantiquement différente de strcpy. Son usage est généralement déconseillé.
La fonction strncpy est destinée à copier une chaine dans un champ de taille fixe. C'est pour cela qu'elle rempli la fin du champ de '\0' si la chaine est plus courte, et qu'elle ne met pas de '\0' terminal si le champ est plus petit que la chaine. Le résultat de strncpy n'est donc pas forcément une chaine!
Pour inserer une chaine dans une autre par exemple: c'est memmove + strncpy pour ne pas mettre justement le '\0'.
Pour insérer une chaine dans une autre, c'est memmove et memcpy.
Bien sûr, stncpy et memcpy font la chose si la taille qu'on leur passe est plus petite que la longueur de la chaine à copier. Mais strncpy implémente toute une logique supplémentaire, qui ne sert à rien dans une insertion, et qui ralentit inutilement l'exécution.
Oui c'est une étrangeté du langage. En fait, le nom de strncpy a été mal choisi.
Citation : C99 Rationale §7.21.2.4 The strncpy function
strncpy was initially introduced into the C library to deal with fixed-length name fields in structures such as directory entries. Such fields are not used in the same way as strings: the trailing null is unnecessary for a maximum-length field, and setting trailing bytes for shorter 5 names to null assures efficient field-wise comparisons. strncpy is not by origin a “bounded strcpy,” and the Committee preferred to recognize existing practice rather than alter the function to better suit it to such use.
@valerianDorcy: Pourquoi avoir effacé toncode? J'ai eu le temps de le voir ... Tu as déterré un vieux sujet de 2008 prolongé jusqu'en 2012. Je l'aurais sans doute fait avec un compteur kilométriqque.
Si ça t'intéresse, crée un nouveau sujet.
- Edité par PierrotLeFou 15 avril 2023 à 1:06:25
Le Tout est souvent plus grand que la somme de ses parties.
Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.
Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre. En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.
Au lieu de déterrer un sujet il est préférable :
soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
soit de créer un nouveau sujet décrivant votre propre contexte
ne pas répondre à un déterrage et le signaler à la modération
Le Tout est souvent plus grand que la somme de ses parties.