2017-06-12 4 views
-2

Pourquoi ne pas les travaux suivants lors de l'utilisation double (il fonctionne à l'aide int)retour double à partir de la fonction C, en utilisant l'expansion macro

test.c

#include "myFcn.h" 
#include <stdio.h> 


int main() { 

    printf("L1: %f \n", myGet_L1()); 

    mySet_L1(10.0); 

    printf("L1: %f \n", myGet_L1()); 

    return 0; 
} 

myFcn.c

#include "myFcn.h" 

double L1 = 0.0; 

double get(double *v) { 
    return *v; 
} 

void set(double *variable, double value) { 
    *variable = value; 
} 

myFcn.h

#ifndef __MYFCN_H__ 
#define __MYFCN_H__ 

extern double L1; 
#define myGet_L1()     get(&L1) 
#define mySet_L1(value)    set(&L1, (value)) 

#endif 

I d on ne voit pas pourquoi cela fonctionne en utilisant int mais pas en double?

+6

Vous avez besoin de prototypes de fonctions pour 'get' et' set' dans test.c. – mch

+0

Pourquoi L1 est-elle déclarée comme une variable spaghetti globale? Une raison particulière, il ne peut pas être privé à myFcn.c? – Lundin

+0

Obtenez un nouveau compilateur! Les déclarations implicites de fonction int ont été interdites il y a 18 ans. Pourquoi quelqu'un utiliserait-il un compilateur si ancien qu'il n'a pas été mis à jour au cours des 18 dernières années? (En cas de gcc plus ancienne que la version 5.0, le problème est souvent une mauvaise configuration.) Utilisez '-std = c11 -pedantic-errors'.) – Lundin

Répondre

1

D'abord un commentaire: activer les avertissements du compilateur! De cette façon, vous pourriez avoir trouvé la réponse vous-même:

Votre unité de compilation pour test.c misses prototypes pour votre get() et set(), ils sont donc implicitement censées être

int get(); 
int set(); 

Ce qui signifie qu'ils prennent un nombre indéterminé d'arguments (promu à int) et renvoie un int. Cela arrive à générer du code de travail si vous utilisez vraiment int pour votre L1, mais ne fonctionne pas avec double.

Solution: Déclarez vos fonctions dans le fichier d'en-tête:

#ifndef __MYFCN_H__ 
#define __MYFCN_H__ 

extern double L1; 
double get(double *); 
void set(double *, double); 

#define myGet_L1()     get(&L1) 
#define mySet_L1(value)    set(&L1, (value)) 

#endif 

Autres notes:

  • Avec le code que vous fournissez, il y a d'autre part aucune raison de avoir la variable elle-même visible à d'autres unités de compilation, donc mieux supprimer la ligne

    extern double L1; 
    
  • identifiants commençant par underscores sont réservés (see this answer pour les règles complètes), de sorte que la dénomination de votre garde macro est pas sage. Utilisez simplement MYFCN_H à la place.

+1

'() 'ne signifie pas" nombre non spécifié d'arguments 'int'", cela signifie "nombre indéterminé d'arguments de types non spécifiés". – unwind

+0

@unwind: fixe, un peu, je ne pense pas que je devrais entrer dans trop de détails sur ce sujet ici ... –

+0

L'OP pourrait utiliser un compilateur de dinosaure qui se conforme uniquement à C90. Puis activer les avertissements pourrait ne pas les aider. – Lundin