Aucun avertissement de gcc lorsque la définition de fonction liée différente source du prototype de fonction en-tête

StackOverflow https://stackoverflow.com/questions/2958036

  •  23-10-2019
  •  | 
  •  

Question

J'ai eu un problème avec une partie de mon code, qui, après quelques itérations semblait lire NaN comme valeur d'un double d'une struct. Je pense avoir trouvé l'erreur, mais me demande encore pourquoi gcc (version 3.2.3 sur Linux avec busybox embarqué) ne m'a pas prévenu. Voici les parties importantes du code:

Un fichier c et son en-tête pour les fonctions d'acquérir des données sur USB:

// usb_control.h
typedef struct{
    double mean;
    short *values;
} DATA_POINTS;

typedef struct{
    int size;
    DATA_POINTS *channel1;
    //....7 more channels
} DATA_STRUCT;

DATA_STRUCT *create_data_struct(int N);  // N values per channel
int free_data_struct(DATA_STRUCT *data);

int aqcu_data(DATA_STRUCT *data, int N);

Un fichier c et en-tête avec fonction d'aide (mathématiques, bitshift, etc ...):

// helper.h
int mean(DATA_STRUCT *data);

// helper.c (this is where the error is obviously)
double mean(DATA_STRUCT *data)
{
    // sum in for loop
    data->channel1->mean = sum/data->N;
    // ...7 more channels
    // a printf here displayed the mean values corretly
}

Le fichier principal

// main.c
#include "helper.h"
#include "usb_control.h"

// Allocate space for data struct
DATA_STRUCT *data = create_data_struct(N);

// get data for different delays
for (delay = 0; delay < 500; delay += pw){
    acqu_data(data, N);
    mean(data);
    printf("%.2f",data->channel1->mean); // done for all 8 channels
    // printf of the mean values first is correct. Than after 5 iterations
    // it is always NaN for channel1. The other channels are displayed correctly;
}

Il n'y avait pas segfaults, ni aucun autre missbehavior, juste NAN pour channel1 dans le fichier principal.

Après avoir trouvé l'erreur, ce qui n'a pas été facile, il était à l'est bien sûr de fixer. Le type de retour de mean(){} a eu tort dans la définition. Au lieu de double mean() il doit être int mean() comme les définit prototypes. Lorsque toutes les fonctions sont mises en un seul fichier, gcc me avertit qu'il ya une redéfinition de la fonction mean(). Mais comme je compile chaque fichier c séparement et les relier ensuite gcc semble manquer cela.

Alors mes questions serait. Pourquoi ne pas que je reçois des avertissements, même non avec gcc -Wall? Ou est-il encore une autre erreur cachée qui est tout simplement pas à l'origine des problèmes maintenant?

Cordialement, Christian

Était-ce utile?

La solution

Lorsque chaque fichier .c est compilé séparément, la seule information que le compilateur sait est le prototype de la fonction que vous avez donné.

Parce que chaque fichier est compilé séparément, il n'y a aucun moyen le processus de compilation de main.c connaît la définition de mean dans helper.c est erroné.

Une fois le fichier .c est compilé, la signature sera dépouillé, de sorte que l'éditeur de liens ne peut pas connaître le mean est mal non plus.

Une solution simple est toujours inclure le fichier .h d'interface dans le fichier .c de mise en œuvre

// in helper.c:
#include "helper.h"
double mean(DATA_STRUCT *data);

Ensuite, le processus de compilation de helper.c remarquerez que le type incohérent et vous avertir.

Autres conseils

Une moyenne est généralement une valeur réelle si deux est ok. Ici, vous définissez mean en retour double, mais le prototype dit int mean(...).

La seule façon gcc peut être conscient du fait qu'il ya une redéfinition, est si la redéfinition se produit pour de vrai ... Lorsque vous compilez des fichiers séparément probablement le prototype moyen est manquant ... il ne figure pas dans votre fragment de code au moins: vous devez inclure helper.h aussi dans helper.c. Ainsi, gcc -c helper.c doit vous donner un avertissement. Je gcc 4.3.2, mais je suis presque sûr qu'il doit en être ainsi aussi pour la version que vous avez. Dans la principale, vous utilisez juste mean, alors voici le gcc fiducies ce qui est dit dans helper.h. Lorsque vous établissez un lien, il n'y a pas plus d'informations sur la taille des arguments et de la valeur de retour, et les mauvaises choses arrivent (comme la lecture d'un int en double).

Un autre détail: vous dites que vous obtenez NaN pour un int de la struct ... eh bien, dans le struct il y a un double et un entier ne peut pas être NaN

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top