IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

fseek & fseeko64


Sujet :

C

  1. #1
    Membre éprouvé Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Par défaut fseek & fseeko64
    Bonjour,

    fseek avec un shift négatif fonctionne trés bien mais fseeko64 avec le même shift négatif déconne completement. Si j'essaye de le faire il m'ecrit un fichier de 4Gb avant de sortir de la fonction !!
    Quelqu'un a-t-il déjà remarqué ca?
    Merci d'avance

  2. #2
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    A tout hasard, tu ne serais pas sur une archi 64 bits?

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Vérifie que ton shift négatif est bien sur 64 bits dès le début.
    Car là, je flaire la mauvaise promotion de (long)-1 en (long long)-1 (passage non-voulu par unsigned long)...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre éprouvé Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Par défaut
    archi 64 ou 32 c'est pareil,

    Pas béte, je vais essayer de passer le -1 en 64 bits directement

    Merci de vos suggestions

  5. #5
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par uriotcea Voir le message
    archi 64 ou 32 c'est pareil,
    Si tu le dis...

  6. #6
    Membre éprouvé Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Par défaut
    Je le dis et je l'ai testé, sur les 2 archi j'ai le même comportement anormal

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    On peut voir le code?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre éprouvé Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Par défaut
    Voici un peu de code. L'un fonctionne l'autre non, sur machine 32 ou 64 bytes.

    Ne fonctionne pas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      f0=fopen64(fich,"rb");
      ...
      long long int dd = -sizeof(int)-3*sizeof(double);
      fseeko64(f0,dd,SEEK_CUR);
    Focntionne, à priori c'est équivalent, sauf erreurr de ma part, au code ci-dessus.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      f0=fopen64(fich,"rb");
      ...
      long long int dd = ftello64(f0);
      dd=dd-sizeof(int)-3*sizeof(double);
      fseeko64(f0,dd,SEEK_SET);

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    sizeof(int) étant unsigned, il y a un risque (je ne connais pas assez bien les règles de promotion pour les calculs).
    Essaie plutôt un truc du genre:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    f0=fopen64(fich,"rb");
    ...
    off64_t sizeOfInt = sizeof(int); /*garanti signé et 64 bits*/
    off64_t sizeOfDouble = sizeof(double);
    off64_t dd = -sizeOfInt - 3*sizeOfDouble;
    assert(off64_t < 0);
    fseeko64(f0, dd, SEEK_CUR);
    Ou au moins, rajoute l'assertion avant ton appel à fseeko64().
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre éprouvé Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Par défaut
    Tu as la solution.
    bravo.
    Je ne suis pas certain d'avoir bien compris la différence entre ta méthode et la mienne, mais c'est clair ca marche.

  11. #11
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Edit: Le post suivant contient les valeurs à jour
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    J'ai modifié mon programme pour faire un test supplémentaire. Les résultats sont édifiants:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    void TestSize2(void) /*ligne 27*/
    {
    	{
    		unsigned short myu16 = 1;
    		signed long mys32 = -myu16;
    		signed long oths32 = 0;
    		oths32 -= myu16;
    		printf("Valeurs 32 bits apres soustraction d'un nombre 16 bits sans signe: %ld, %ld.\n", mys32, oths32);
    	}
     
    	{
    		unsigned long myu32 = 1;
    		signed long mys32 = -myu32; /* ligne 39 ici */
    		signed long oths32 = 0;
    		oths32 -= myu32;
    		printf("Valeurs 32 bits apres soustraction d'un nombre 32 bits sans signe: %ld, %ld.\n", mys32, oths32);
    	}
     
    	{
    		unsigned long myu32 = 1;
    		signed long long mys64 = -myu32; /* ligne 47 ici */
    		signed long long oths64 = 0;
    		oths64 -= myu32;
    		printf("Valeurs 64 bits apres soustraction d'un nombre 32 bits sans signe: %lld, %lld.\n", mys64, oths64);
    	}
     
    	{
    		signed long mys32 = -sizeof(int); /* ligne 54 ici */
    		signed long oths32 = 0;
    		signed long long mys64 = -sizeof(int); /* ligne 56 ici */
    		signed long long oths64 = 0;
    		oths32 -= sizeof(int);
    		oths64 -= sizeof(int);
    		printf("Valeurs 32 bits apres soustraction d'un sizeof: %ld, %ld.\n", mys32, oths32);
    		printf("Valeurs 64 bits apres soustraction d'un sizeof: %lld, %lld.\n", mys64, oths64);
    	}
    }

    Voici la sortie de Visual:
    Code X : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    testsize.c(39) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
    testsize.c(47) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
    testsize.c(54) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
    testsize.c(56) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
    Et la sortie du programme:
    Code X : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Valeurs 32 bits apres soustraction d'un nombre 16 bits sans signe: -1, -1.
    Valeurs 32 bits apres soustraction d'un nombre 32 bits sans signe: -1, -1.
    Valeurs 64 bits apres soustraction d'un nombre 32 bits sans signe: 4294967295, -1.
    Valeurs 32 bits apres soustraction d'un sizeof: -4, -4.
    Valeurs 64 bits apres soustraction d'un sizeof: 4294967292, -4.
    Il est intéressant de constater que ça ne se passe pas avec des short, mais que ça agit sur les long (et leur promotion en 64 bits). Sans doute est-ce dû à la taille du type int sur ce système (32 bits, la même qu'un long).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #13
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ce qui nous donne une grille des résultats du - unaire sur des nombres non-signés:
    • '-' sur unsigned short --> signed int
    • '-' sur unsigned int --> unsigned int
    • '-' sur unsigned long --> unsigned long
    • '-' sur unsigned long long --> unsigned long long
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par uriotcea Voir le message
    Ne fonctionne pas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
      f0=fopen64(fich,"rb");
      ...
      long long int dd = -sizeof(int)-3*sizeof(double);
      fseeko64(f0,dd,SEEK_CUR);
    Focntionne, à priori c'est équivalent, sauf erreurr de ma part, au code ci-dessus.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      f0=fopen64(fich,"rb");
      ...
      long long int dd = ftello64(f0);
      dd=dd-sizeof(int)-3*sizeof(double);
      fseeko64(f0,dd,SEEK_SET);
    Plusieurs choses, déjà c'est une mauvaise habitude que d'appeller les fonctions suffixés par 64.
    Ensuite, les 2 codes précédents ne sont pas du tout équivalents, comme le fait remarqué médinoc, il y a des soucis de promotion:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long long int dd = -sizeof(int)-3*sizeof(double);
    sizeof(int) vaut 4 (mettons que nous somme sur une archi ILP32)
    -sizeof(int) vaut 4 294 967 292 (principe de la réduction modulo)
    sizeof(double) vaut 8
    total = 4 294 967 292 - 3 * 8 = 4294967268

    deuxième cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dd=dd-sizeof(int)-3*sizeof(double);
    mettons que dd vaut 50 au départ
    total = 50 - 4 - 3 * 8 = 22

    Dans le premier cas, on applique un opérateur unaire sur sizeof(int) qui conserve son type soit size_t, on prend sa valeur soit 4, que l'on rend négative soit -4, auquel on apllique la règle du modulo : -4 + (INT_MAX + 1)

    Dans le second cas, c'est différent, sizeof(int) est soustrait à un long long, il est donc lui même promu en long long, ça valeur ne change pas.

  15. #15
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Citation Envoyé par nicolas.sitbon
    c'est une mauvaise habitude que d'appeller les fonctions suffixés par 64.
    Je proteste.

    Je sais que c'est non-portable, mais sur un système où ça marche, ça n'est pas "mauvais". De plus, sur un système 32 bits, c'est souvent le seul moyen d'opérer sur des fichiers de taille supérieure à 4Go (ou même 2Go quand on ne gère pas correctement la taille).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    Membre éprouvé Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Par défaut
    Juste une remarque, si tu es sous windows %lld n'est pas capable d'afficher correctement des 64b mais I64i% oui
    Enfin je parle de gcc ici
    Ensuite ces fonctions 64 sont justement faites pour assuré la portabilité descedente de 64 vers 32 et foncionnent aussi bien sous windows que sur linux
    Que demander de plus !

  17. #17
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ça dépend si tu utilises une C Run-Time Library (CRT) obsolète ou non.
    La CRT de Visual 2005 affiche parfaitement les %lld. Celle de Visual 6 ne le fait pas, vu qu'elle date d'avant.
    Et MinGW utilise la CRT de Visual 6. C'est de leur faute.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  18. #18
    Membre éprouvé Avatar de uriotcea
    Homme Profil pro
    Ingénieur / physicien
    Inscrit en
    Septembre 2003
    Messages
    1 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur / physicien
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 301
    Par défaut
    Ok merci pour l'info, j'espere qu'il vont shifter parce que c'est plutot ennuyeux d'avoir à ecrire les choses différent suivant le syteme

Discussions similaires

  1. Compréhension de fseek
    Par Argonz dans le forum C
    Réponses: 9
    Dernier message: 12/01/2004, 15h01
  2. Probleme avec fseek
    Par Bjorn dans le forum C
    Réponses: 5
    Dernier message: 04/08/2002, 07h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo