Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

warning: assignment makes pointer from integer without a cast

14 réponses
Avatar
JKB
Bonsoir à tous,

J'ai honte de poser la question que je vais vous soumettre, mais je
ne comprends pas mon erreur.

J'ai écrit il y a plusieurs années une fonction dont le prototype
est le suivant :

unsigned char *
formateur_flux(struct_processus *s_etat_processus, unsigned char *donnees,
integer8 *longueur);

integer8 est, comme son nom l'indique, un entier de 64 bits (parce
qu'il y a des vrais bouts de Fortran avec des INTEGER*8 dedans).
*longueur est un paramètre de sortie.

Cette fonction donne satisfaction. Grosso modo, elle prend une
chaîne et transforme un certain nombre de codes d'échappement avant
de renvoyer une nouvelle chaine allouée dans la fonction.

Je viens de corriger un code d'un stagiaire et j'ai un warning (en
fait une erreur puisque ça termine par un segfault) que je ne
comprends pas.

J'ai rajouté une verrue, façon quick and dirty dans une fonction
erronée qui oubliait de traiter les caractères d'échappement :

{
unsigned char *__a; integer8 __l;
__a = formateur_flux(rpl_arguments->s_etat_processus, c, &__l);
if (__a == NULL) return NULL;
free(c); c = __a;
}

et je me prends :

ngspice.rplc: In function ‘__external_loadCircuit’:
ngspice.rplc:160:9: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
__a = formateur_flux((*rpl_arguments).s_etat_processus, c, &__l);
^
ngspice.rplc:162:16: warning: pointer targets in assignment differ in signedness [-Wpointer-sign]
free(c); c = __a;
^

J'ai beau regarder dans tous les sens. c est un unsigned char *.
__a aussi. formateur_flux() renvoie un unsigned char *. Pourquoi
cette affectation pose-t-elle problème ?

Je sèche lamentablement.

Bien cordialement,

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
=> http://loubardes.de-charybde-en-scylla.fr

4 réponses

1 2
Avatar
JKB
Le Thu, 31 May 2018 20:32:47 +0200,
Lucas Levrel écrivait :
Le 31 mai 2018, à 06:04, JKB a écrit :
Bref, je me suis fait avoir par un garde-fou que j'avais moi-même
installé et par un warning de gcc pas vraiment pertinent.

Dans le man gcc je lis :
-Wall turns on the following warning flags:
... -Wimplicit-function-declaration
Tu n'utilises pas -Wall ?

Si, naturellement. Même -Wextra en prime.
JKB
--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
=> http://loubardes.de-charybde-en-scylla.fr
Avatar
Pascal J. Bourguignon
JKB writes:
Par ailleurs, une fonction définie dans foo.c sera obligatoirement
déclarée (avec un prototype complet) dans foo.h, et on trouvera un
'#include "foo.h"' à la fois dans foo.c et dans tous les fichiers
bar.c qui utilisent cette fonction.

C'est un principe que j'utilise. Le #define RPLARGS est juste là
pour éviter d'exporter des prototypes internes qui n'ont pas à être
vus dans des modules pour éviter que les gens fassent n'importe
quoi avec des fonctions qu'ils ne maîtrisent pas ou n'ont pas à
utiliser directement... De la même manière, certains types sont
rendus opaques pour les mêmes raisons. Bref, je me suis fait avoir
par un garde-fou que j'avais moi-même installé et par un warning de
gcc pas vraiment pertinent.

Ce qui ne doit pas être vu à l'extérieur, n'a absolument rien à faire
dans l'entête publique du module !
Au pire, si tu as un module qui est implémenté sur plusieurs fichiers,
tu peux avoir un entête privé.
Par exemple:
foo.h entête publique
foo_impl_part1.h entête privé
foo_impl_part1.c #include <foo.h> #include "foo_impl_part1.h"
foo_impl_part2.h entête privé
foo_impl_part2.c #include <foo.h> #include "foo_impl_part2.h"
foo.c #include <foo.h> #include "foo_impl_part1.h" #include "foo_impl_part2.h"
--
__Pascal J. Bourguignon
http://www.informatimago.com
Avatar
espie
In article ,
JKB wrote:
C'est un principe que j'utilise. Le #define RPLARGS est juste là
pour éviter d'exporter des prototypes internes qui n'ont pas à être
vus dans des modules pour éviter que les gens fassent n'importe
quoi avec des fonctions qu'ils ne maîtrisent pas ou n'ont pas à
utiliser directement... De la même manière, certains types sont
rendus opaques pour les mêmes raisons. Bref, je me suis fait avoir
par un garde-fou que j'avais moi-même installé et par un warning de
gcc pas vraiment pertinent.

Content que tu aies trouve, mais en poussant un peu le trait sur ce que je
disais, t'as quand meme une methodologie de martien.
Ton code est trop fute pour toi-meme, c'est quand meme un peu con.
Et c'est quand meme bizarre que tu viennes demander de l'aide pour un
truc que t'aurais du trouver tout seul directement.
Vu que tu es sur un compilo qui a ca, sur ce genre de bugs, la premiere
ligne, ca devrait etre de faire tourner
gcc -save-temps
*PUIS* de regarder la tronche du code genere.
Et d'en virer des lignes jusqu'a ce que tu aies un exemple minimal qui
deconne (enfin suffisamment petit pour pouvoir le poster).
Si a ce stade t'as toujours pas trouve, ben tu postes ici.
Mais ouais, on dit au reste du monde "postez des exemples complets".
Ca s'applique aussi a toi.
Et depuis le temps que tu programmes, que tu ne connaisses pas la methodo
de base pour debugguer un warning touffu, c'est quand meme un poil
surprenant.
(note que c'est ce qu'on utilise quand on n'a pas trop le choix, par
exemple quand c'est gcc lui-meme qui segfaulte sur du code complique...)
Avatar
JKB
Le Fri, 1 Jun 2018 00:06:10 +0000 (UTC),
Marc Espie écrivait :
In article ,
JKB wrote:
C'est un principe que j'utilise. Le #define RPLARGS est juste là
pour éviter d'exporter des prototypes internes qui n'ont pas à être
vus dans des modules pour éviter que les gens fassent n'importe
quoi avec des fonctions qu'ils ne maîtrisent pas ou n'ont pas à
utiliser directement... De la même manière, certains types sont
rendus opaques pour les mêmes raisons. Bref, je me suis fait avoir
par un garde-fou que j'avais moi-même installé et par un warning de
gcc pas vraiment pertinent.

Content que tu aies trouve, mais en poussant un peu le trait sur ce que je
disais, t'as quand meme une methodologie de martien.

Merci, mais on va arrêter là.
Ton code est trop fute pour toi-meme, c'est quand meme un peu con.
Et c'est quand meme bizarre que tu viennes demander de l'aide pour un
truc que t'aurais du trouver tout seul directement.
Vu que tu es sur un compilo qui a ca, sur ce genre de bugs, la premiere
ligne, ca devrait etre de faire tourner
gcc -save-temps
*PUIS* de regarder la tronche du code genere.

Figure-toi que je l'ai fait. C'est comme ça que j'ai pu identifier
la ligne provoquant l'erreur en question. Tu m'excusera d'avoir raté
une ligne de prototype dans un fichier préprocessé de 2Mo d'autant
plus que _jamais_ gcc n'a ralé sur un prototype manquant (le 6 et
toutes les versions précédentes le faisaient) et que je ne me focalisais
pas sur cette histoire de prototype.
Juste pour info, le code fautif renvoie un warning sur une absence
de prototype avec gcc 5.5.0 et 6.4.0 (NetBSD) mais pas avec le
7.3.0 (toujours sous NetBSD). Je viens de tester ce matin.
Et d'en virer des lignes jusqu'a ce que tu aies un exemple minimal qui
deconne (enfin suffisamment petit pour pouvoir le poster).
Si a ce stade t'as toujours pas trouve, ben tu postes ici.
Mais ouais, on dit au reste du monde "postez des exemples complets".
Ca s'applique aussi a toi.

J'aurais pu te poster les fichiers d'en-têtes (protoypes et macros)
ainsi que le fichier source qui est un truc qui ressemble à cela :
declareExternalFunction(getVecInfo)
declareObject(object1);
declareObject(object2);
integer i;
integer nod;
pvector_info vector;
string name;
HEADER
declareHelpString("Return data");
numberOfArguments(1);
FUNCTION
pullFromStack(object1, string);
returnOnError(freeObject(object1));
getString(object1, name);
vector = ngGet_Vec_Info(name);
nod = vector->v_length;
createRealVectorObject(object2, nod);
loop(i = 0, i lt nod, postIncr(i))
setRealIntoVector(object2, vector->v_realdata[i], i + 1);
endLoop
freeObject(object1);
pushOnStack(object2);
END
endExternalFunction
Tu m'aurais répondu que ce n'est pas du C et tu aurais eu raison.
Si j'avais filé le bout de code sorti du préprocesseur, j'aurais pu
poster quelque chose du genre :
; char **tableau; char *ptr1, *ptr2; int drapeau; unsigned long i; void *s_etat_processus; s_etat_processus = (*rpl_arguments).s_etat_processus; if (strcmp(version, _d_version_rpl) != 0) { do { if (((*rpl_arguments).erreur != 0) && ((*rpl_arguments).type_erreur == 'S')) return 0; } while(0); do { librpl_std_fprintf(stdout, "Versions mismatch : library %s, expected %sn", _d_version_rpl, version); fflush((stdout == stdout) ? stderr : stdout); } while(0); (*nb_symbols) = -1; return(((void *)0)); } (*nb_symbols) = 0; ptr1 = arguments; drapeau = 0; while((*ptr1) != 0) { if (((*ptr1) != ',') && ((*ptr1) != ' ')) drapeau = -1; ptr1++; } if (drapeau == 0) return(((void *)0)); ptr1 = arguments; (*nb_symbols) = 1; while((*ptr1) != 0) if ((*ptr1++) == ',') (*nb_symbols)++; if ((tableau = rpl_malloc(s_etat_processus, (*nb_symbols) * sizeof(char *))) == ((void *)0)) return(((void *)0)); ptr2 = arguments; i = 0; while(*ptr2 != 0) { while(((*ptr2) == ' ') || ((*ptr2) == ',')) ptr2++; ptr1 = ptr2; while(((*ptr2) != 0) && ((*ptr2) != ',') && ((*ptr2) != ' ')) ptr2++; if ((tableau[i] = rpl_malloc(s_etat_processus, (ptr2 + 2 + strlen(__library_name) - ptr1) * sizeof(unsigned char))) == ((void *)0)) return(((void *)0)); sprintf(tableau[i], "%s$", __library_name); strncat(&tableau[i][strlen(tableau[i])], ptr1, ptr2 - ptr1); i++; if ((*ptr2) != 0) { while((*ptr2) == ' ') ptr2++; if ((*ptr2) == ',') ptr2++; } } (*nb_symbols) = i; return(tableau); }
if (__validation_instruction == ((logical1) -1L)) return 0; if (__presence_aide == ((logical1) 0L)) { do { (*rpl_arguments).erreur = 148; (*rpl_arguments).type_erreur = 'S'; (*rpl_arguments).message_erreur = (unsigned char *) "Help string not defined"; return 0; } while(0); } else if (__presence_validation == ((logical1) 0L)) { do { (*rpl_arguments).erreur = 148; (*rpl_arguments).type_erreur = 'S'; (*rpl_arguments).message_erreur = (unsigned char *) "Number of arguments not defined"; return 0; } while(0); } __indice_bit = 0; __indice_bloc = 0; __taille_bloc = 0; __type = 0; __masque = 0; {
do { do { if (((*rpl_arguments).erreur != 0) && ((*rpl_arguments).type_erreur == 'S')) return 0; } while(0); (*rpl_arguments).l_base_pile = librpl_depilement_pile_operationnelle(rpl_arguments, &
qui est certainement du C pour le coup, mais que personne n'aurait lu.
Même remis en forme, c'est particulièrement incompréhensible.
Tu m'excuseras donc d'avoir opté pour un juste milieu.
Et depuis le temps que tu programmes, que tu ne connaisses pas la methodo
de base pour debugguer un warning touffu, c'est quand meme un poil
surprenant.
(note que c'est ce qu'on utilise quand on n'a pas trop le choix, par
exemple quand c'est gcc lui-meme qui segfaulte sur du code complique...)

Je te prie de ne pas faire d'hypothèses sur mes méthodes de travail.
JKB
PS: je ne répondrai pas.
--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
=> http://loubardes.de-charybde-en-scylla.fr
1 2