CONNEXION
  • RetourJeux
    • Tests
    • Soluces
    • Previews
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Tous les Jeux
  • RetourActu
    • Culture Geek
    • Astuces
    • Réalité Virtuelle
    • Rétrogaming
    • Toutes les actus
  • Bons plans
  • RetourHigh-Tech
    • Actus JVTECH
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTECH
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch
    • Xbox Series
    • Overwatch 2
    • FUT 23
    • League of Legends
    • Genshin Impact
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • PS4
  • One
  • Switch
  • Wii U
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Etoile Abonnement RSS

Sujet : printf("blabla");

DébutPage précedente
«1  ... 135136137138139140141142143144145  ... 156»
Page suivanteFin
lokilok lokilok
MP
Niveau 11
08 août 2016 à 14:38:50

En vrai je me posais surtout la question dans le cas de l'héritage, le reste c'était que pour avoir confirmation, mais j'pense que j'vais tout inclure effectivement.

katk katk
MP
Niveau 10
08 août 2016 à 15:52:47

tu voulais pas plutot utiliser write ? [[sticker:p/1kki]]

rangerprice rangerprice
MP
Niveau 10
08 août 2016 à 23:58:09

ah oui c'est write() pas print() en effet kaTk :hap:

godrik godrik
MP
Niveau 26
09 août 2016 à 00:02:07

Et pourquoi c'est sale printf?

katk katk
MP
Niveau 10
09 août 2016 à 00:24:24

parce que c'est pas code maison je dirais, moi-meme ca me fait mal au coeur de l'utiliser apres un mois de piscine a 42
tiens je viens de remarquer que LGV est passe modo, j'ai eu un bon mois d'absence

[DenshaOtoko] [DenshaOtoko]
MP
Niveau 24
09 août 2016 à 00:55:20

Le 08 août 2016 à 08:38:20 rangerprice a écrit :

Le 08 août 2016 à 04:11:35 whiteapplex a écrit :

Le 08 août 2016 à 04:10:16 rangerprice a écrit :
Au passage il faudrait changer le titre du topic en "print(1, "blabla", 6);" car utiliser printf comme ça c'est sale :hap:

Et le "1" il est pas sale :hap: ?

Si ça te dit pas trop on peut écrire "print(STDOUT, "blabla", 6);" et imaginer qu'il y a un préprocesseur derrière qui initialise STDOUT à 1 :hap:
Mais les initiés savent déjà que 1 = stdout, seul les vrais comprendront et c'est bien comme ça:hap:

les constantes (pour les fd donc int) STDOUT STDERR et STDIN existent déjà dans stdio.h

pareil en version FILE* , sauf que là c'est en miniscule, stdout, stderr, et stdin

et printf c'est pas sale, printf fait un appel système à write de toutes façon

après peut être que tu veux dire qu'il faut mieux faire fprintf(stdout, .. pour pouvoir swapé plus facilement l'instruction en un message d'erreur, après dans ce cas autant utiliser un bon logger directement

Message édité le 09 août 2016 à 00:59:26 par [DenshaOtoko]
godrik godrik
MP
Niveau 26
09 août 2016 à 01:06:13

parce que c'est pas code maison je dirais, moi-meme ca me fait mal au coeur de l'utiliser apres un mois de piscine a 42

Et alors? Est ce que tu ecrirais printf differement? Est ce que tu as ecris write ?
N'est ce pas la base du syndrome NIH? ( qui est certainement ce qu'il y a de pire dans le domaine)

Note en passant que write et printf ne font pas du tout la meme chose.

godrik godrik
MP
Niveau 26
09 août 2016 à 01:08:15

et printf c'est pas sale, printf fait un appel système à write de toutes façon

Note que ce n'est pas vrai ca! printf ne fait pas systematiquement un appel a write.

[DenshaOtoko] [DenshaOtoko]
MP
Niveau 24
09 août 2016 à 01:11:24

Le 09 août 2016 à 01:08:15 godrik a écrit :

et printf c'est pas sale, printf fait un appel système à write de toutes façon

Note que ce n'est pas vrai ca! printf ne fait pas systematiquement un appel a write.

ouais, c'est seulement quand il y a un \n où il flush c'est ça ?

katk katk
MP
Niveau 10
09 août 2016 à 02:49:38

Et alors? Est ce que tu ecrirais printf differement?

certainement moins bien

Est ce que tu as ecris write ?

bien sur que non, mais apres avoir passe du temps a ne travailler qu'avec les fonctions de base qui permettent pas grand chose a elles seules on s'y habitue et on prend gout a tout refaire (enfin refaire printf ca releve plus du calvaire), comme tu dis c'est la base du NIH

godrik godrik
MP
Niveau 26
09 août 2016 à 03:40:09

Le 09 août 2016 à 01:11:24 [DenshaOtoko] a écrit :

Le 09 août 2016 à 01:08:15 godrik a écrit :

et printf c'est pas sale, printf fait un appel système à write de toutes façon

Note que ce n'est pas vrai ca! printf ne fait pas systematiquement un appel a write.

ouais, c'est seulement quand il y a un \n où il flush c'est ça ?

Oula, c'est plus complique que ca en fait (j'ai ete lire posix et la gnulibc).

La gnulibc[1] dit qu'elle flush dans ces conditions la :
-When you try to do output and the output buffer is full.
-When the stream is closed. See Closing Streams.
-When the program terminates by calling exit. See Normal Termination.
-When a newline is written, if the stream is line buffered.
-Whenever an input operation on any stream actually reads data from its file.

En regardant posix[2] on se rend compte qu'il y a plein de comportement pas forcement attendu

A file may be subsequently reopened, by the same or another program execution, and its contents reclaimed or modified (if it can be repositioned at its start). If the main() function returns to its original caller, or if the exit() function is called, all open files are closed (hence all output streams are flushed) before program termination. Other paths to program termination, such as calling abort(), need not close all files properly.

Donc si tu prends sigterm, le buffer pars dans /dev/null

When a stream is "fully buffered", bytes are intended to be transmitted as a block when a buffer is filled. When a stream is "line buffered", bytes are intended to be transmitted as a block when a <newline> byte is encountered. Furthermore, bytes are intended to be transmitted as a block when a buffer is filled, when input is requested on an unbuffered stream, or when input is requested on a line-buffered stream that requires the transmission of bytes

Est ce que ca flush sur un newline depends de si le fd est "fully buffered" ou "lined buffered", trop lol hein :) Qu'en est il de stdout, stdin, et stderr.

At program start-up, three streams are predefined and need not be opened explicitly: standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). When opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.

Trop lol, stderr et stdout peuvent ne pas se comporter pareil :)

Et que dis le man posix de fopen:

When opened, a stream is fully buffered if and only if it can be determined not to refer to an interactive device.

Et naturellement un pipe c'est pas interactif. On voit ca super bien en executant ca:


erik@eriklaptop2:/tmp$ cat foo.c
#include <stdio.h>
#include <unistd.h>

int main () {
  printf ("bla\n");
  sleep(4);
  printf ("bla\n");
}
erik@eriklaptop2:/tmp$ make foo
cc     foo.c   -o foo
erik@eriklaptop2:/tmp$ ./foo
bla
bla
erik@eriklaptop2:/tmp$ ./foo | cat
bla
bla
erik@eriklaptop2:/tmp$

ou le premier ./foo est line buffered, mais le deuxieme est fully buffered.

Note que je n'es pas vu dans posix (mais peut etre je l'ai loupe) la garantie que tout les output sont flushe quand il y a n'importe quel input.

Les interactions entre fd et stream et entre steam et fork/exec sont bien sympa aussi.

[1] http://www.gnu.org/software/libc/manual/html_node/Flushing-Buffers.html
[2] http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_05

godrik godrik
MP
Niveau 26
09 août 2016 à 03:45:44

Est ce que tu as ecris write ?

bien sur que non, mais apres avoir passe du temps a ne travailler qu'avec les fonctions de base qui permettent pas grand chose a elles seules on s'y habitue et on prend gout a tout refaire (enfin refaire printf ca releve plus du calvaire), comme tu dis c'est la base du NIH

Clairement ca a une valeure pedagogique de travailler a partir des fonctions exposer par le systeme. Il faut avoir ecrit malloc pour se rendre compte de l'horreur qui se passe en cas de buffer overflow/underflow.

Mais concretement un dev qui utilise write au lieu de printf ou fwrite, il cherche un peu a se faire taper. Principalement a cause des differences de buffering qui donne ce comportement wtf et inatendu, mais completement comprehensible une fois qu'on creuse:


erik@eriklaptop2:/tmp$ cat foo.c
#include <stdio.h>
#include <unistd.h>

int main () {
  printf ("bla\n");
  write (1, "foo\n", 4);
  printf ("bla\n");
}
erik@eriklaptop2:/tmp$ make foo
cc     foo.c   -o foo
erik@eriklaptop2:/tmp$ ./foo
bla
foo
bla
erik@eriklaptop2:/tmp$ ./foo | cat
foo
bla
bla
erik@eriklaptop2:/tmp$ 
Message édité le 09 août 2016 à 03:46:15 par godrik
[DenshaOtoko] [DenshaOtoko]
MP
Niveau 24
09 août 2016 à 05:46:07

merci pour le résumé intéressant !

rangerprice rangerprice
MP
Niveau 10
09 août 2016 à 08:23:12

Godrik :d) Je voulais remplacer le titre du topic par un write() car printf n'est pas approprié(semantiquement).
printf veut dire print formated et ça affiche une chaine de caractère formaté avec les paramètres passés, mais en l'occurence on passe aucun paramètre(printf('blabla')), et on se contente d'afficher une rvalue.

Printf -- qui n'est pas fait pour afficher betement des rvalue -- va passer "blabla" au moulin pour voir si il y a des paramètres à substituer dans la chaine, ceci coute en performance et dans certains cas, en sécurité aussi.
Si le premier paramètre de printf() est une valeur qu'un utilisateur peut modifier, alors le programme est vulnerable et peut être facilement exploité. :hap:

C'est vrai quoi :hap:
Appeler printf pour afficher une chaine de caractère qui n'est pas formaté n'a pas de sens :hap:

godrik godrik
MP
Niveau 26
09 août 2016 à 21:24:21

oui et non. Je ne suis pas completement convaincu par ton argument. En l'occurence, la chaine est statique et est donc controle par le developpeur. Ca a l'avantage compare a write ou a printf de ne pas avoir a specifier la taille de la chaine qui peut etre un probleme si c'est encode statiquement comme tu l'avais fait avec
write (1, "blabla", 6);
Deja ca bypass le buffer de la libc, ce qui est souvent une mauvaise idee a moins que tout le code n'utilise pas al libc. Tu pourrais contourner les deux problemes avec
fwrite (1, "blabla", strlen("blabla"));
mais c'est quand meme une bombe a retardement parceque tu pourrais changer l'un et oublier l'autre. Alors tu pourrais faire
const char * foo = "blabla"; fwrite (foo, strlen(foo), 1, 1);
mais ca fait une ligne de plus pour pas grand chose.
Mais en fait, c'est meme pire que ca parceque ni write ni fwrite ne garantissent que l'integralite du buffer ne sera ecrit. Donc en fait, le code correct est:
{ size_t len; const char * foo = "blabla"; while (len = strlen(foo)) foo += fwrite (foo, len, 1, 1); }
Ce qui devient franchement casse couille a ecrire.

Et en plus, ca ne me parait pas clair que c'est beaucoup plus performant que
printf("blabla");
parce ca force a traverser la chaine au moins deux fois (et potentiellement plus si pour une raison bizarre, l'IO ne se fait pas en une fois.). Alors que l'appel a printf ne traversera la chaine qu'une seule fois et garantie que tout sera ecrit (sauf ferror). Apres je suis d'accord qu'il y a un petit overhead lie au decodage au cas ou il y aurait un format.
printf ("%s", "blabla");
est certainement une meilleur option.

Donc non, utiliser write c'est juste une mauvaise idee.

Message édité le 09 août 2016 à 21:26:45 par godrik
Korback Korback
MP
Niveau 10
10 août 2016 à 20:19:53

Au pire on se casse pas la tête et on met Console.WriteLine("Blabla");.

Message édité le 10 août 2016 à 20:20:50 par Korback
lokilok lokilok
MP
Niveau 11
12 août 2016 à 15:58:56

En incluant uniquement ce que j'utilise au lieu d'inclure les headers générique de Qt j'suis passé de plus de 2 minutes de compilation en debug à 1 minute, j'pensais pas que je gagnerais autant :(

Message édité le 12 août 2016 à 16:00:11 par lokilok
godrik godrik
MP
Niveau 26
12 août 2016 à 16:04:31

lokilok, tu connais make -j ?

lokilok lokilok
MP
Niveau 11
12 août 2016 à 16:09:52

Non, c'est quoi ?

lokilok lokilok
MP
Niveau 11
12 août 2016 à 16:16:35

Ah ok je vois, c'est pour compiler plusieurs parties du programme en parallèle au lieu de les faire les unes à la suite des autres c'est ça ? J'vais voir l'essayer voir si ça diminue beaucoup ou pas (j'ai qu'un dual core).

DébutPage précedente
Page suivanteFin
Répondre
Prévisu
?
Victime de harcèlement en ligne : comment réagir ?
Infos 0 connecté(s)

Gestion du forum

Modérateurs : godrik, LGV
Contacter les modérateurs - Règles du forum

Sujets à ne pas manquer

La vidéo du moment