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

10 réponses

1 2
Avatar
Olivier Miakinen
Le 30/05/2018 17:46, JKB a écrit :
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);
[...]
{
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);
^

Question bête : le prototype de la fonction est-il écrit quelque part
dans ngspice.rplc, avant son utilisation ?
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 *.

Question bête numéro 2 : c est-il aussi déclaré comme unsigned char *
dans ngspice.rplc, avant son utilisation ?
Question de simple curiosité : pourquoi cette extension .rplc au lieu
de .c ?
--
Olivier Miakinen
Avatar
Olivier Miakinen
Le 30/05/2018 17:56, je répondais à JKB :
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);
^

Question bête : le prototype de la fonction est-il écrit quelque part
dans ngspice.rplc, avant son utilisation ?

Je complète ma réponse.
Sans un prototype de formateur_flux dans ngspice.rplc, le compilateur
considèrera par défaut que cette fonction retourne un int. Or si les
int sont plus petits que les pointeurs (par exemple int sur 32 bits
et pointeur sur 64 bits), seule une partie de la valeur du pointeur
sera copiée dans __a, d'où le segfault quand tu essayes de le
déréférencer.
--
Olivier Miakinen
Avatar
JKB
Le Wed, 30 May 2018 17:56:48 +0200,
Olivier Miakinen <om+ écrivait :
Le 30/05/2018 17:46, JKB a écrit :
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);
[...]
{
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);
^

Question bête : le prototype de la fonction est-il écrit quelque part
dans ngspice.rplc, avant son utilisation ?

Oui.
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 *.

Question bête numéro 2 : c est-il aussi déclaré comme unsigned char *
dans ngspice.rplc, avant son utilisation ?

Oui (mais au point où j'en suis aucune question n'est bête).
Question de simple curiosité : pourquoi cette extension .rplc au lieu
de .c ?

Parce qu'en fait, c'est un langage de macros (pour aider les gens qui
ne savent pas écrire) qui est compilé par gcc. J'ai poussé le vice à
regarder la sortie du préprocesseur, rien ne me saute aux yeux.
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
Avatar
JKB
Le Wed, 30 May 2018 18:04:41 +0200,
Olivier Miakinen <om+ écrivait :
Le 30/05/2018 17:56, je répondais à JKB :
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);
^

Question bête : le prototype de la fonction est-il écrit quelque part
dans ngspice.rplc, avant son utilisation ?

Je complète ma réponse.
Sans un prototype de formateur_flux dans ngspice.rplc, le compilateur
considèrera par défaut que cette fonction retourne un int. Or si les
int sont plus petits que les pointeurs (par exemple int sur 32 bits
et pointeur sur 64 bits), seule une partie de la valeur du pointeur
sera copiée dans __a, d'où le segfault quand tu essayes de le
déréférencer.

Rhoh pétard. Je me filerais des baffes !
Début de mon fichier de macros de programmation :
#ifndef INCLUSION_RPLARGS
# define INCLUSION_RPLARGS
/*
=============================================================================== INCLUSIONS
=============================================================================== */
// Si TYPE_DECLARATION est défini, toutes les structures internes du RPL/2
// sont exposés pour travailler sur des nouveaux types de données.
# ifndef TYPE_DECLARATION
# define RPLARGS
# define struct_processus void
# endif
# include "rpl.h"
Note bien le define RPLARGS (puisque TYPE_DECLARATION n'est pas
défini). Et dans mes prototypes :
#ifndef RPLARGS
...
unsigned char *formateur_flux(struct_processus *s_etat_processus,
unsigned char *donnees, integer8 *longueur);
...
#endif
Désolé pour le bruit et merci pour l'oeil neuf.
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
Avatar
JKB
Le Wed, 30 May 2018 18:04:41 +0200,
Olivier Miakinen <om+ écrivait :
Le 30/05/2018 17:56, je répondais à JKB :
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);
^

Question bête : le prototype de la fonction est-il écrit quelque part
dans ngspice.rplc, avant son utilisation ?

Je complète ma réponse.
Sans un prototype de formateur_flux dans ngspice.rplc, le compilateur
considèrera par défaut que cette fonction retourne un int. Or si les
int sont plus petits que les pointeurs (par exemple int sur 32 bits
et pointeur sur 64 bits), seule une partie de la valeur du pointeur
sera copiée dans __a, d'où le segfault quand tu essayes de le
déréférencer.

Ce qui est assez surprenant, c'est que le compilo ne me dise pas que
la fonction n'est pas prototypée. Je lui ai fait bêtement
confiance...
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
Olivier Miakinen
Le 30/05/2018 18:17, JKB a écrit :
Rhoh pétard. Je me filerais des baffes !
Début de mon fichier de macros de programmation :
#ifndef INCLUSION_RPLARGS
# define INCLUSION_RPLARGS
/*
=============================================================================== > INCLUSIONS
=============================================================================== > */
// Si TYPE_DECLARATION est défini, toutes les structures internes du RPL/2
// sont exposés pour travailler sur des nouveaux types de données.
# ifndef TYPE_DECLARATION
# define RPLARGS
# define struct_processus void
# endif
# include "rpl.h"
Note bien le define RPLARGS (puisque TYPE_DECLARATION n'est pas
défini). Et dans mes prototypes :
#ifndef RPLARGS
...
unsigned char *formateur_flux(struct_processus *s_etat_processus,
unsigned char *donnees, integer8 *longueur);
...
#endif

Ah oui, je comprends que ce soit difficile à lire et source d'erreur,
ce #define qui dépend d'un #ifndef avec un autre nom.
Pour ma part, autant que possible j'essaye que mes #include soient
inconditionnels (donc pas dans un #if ... #endif), et ils ressemblent
à ça :
--------------------------------------
/*
* Fichier foo.h
*/
#ifndef _FOO_H
#define _FOO_H
...
...
...
#endif /* _FOO_H */
--------------------------------------
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.
--
Olivier Miakinen
Avatar
Pascal J. Bourguignon
JKB writes:
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 protot ype
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 foncti on
erronée qui oubliait de traiter les caractères d'échappem ent :
{
unsigned char *__a; integer8 __l;
__a = formateur_flux(rpl_arguments->s_etat_processus, c, &__l);
if (__a == NULL) return NULL;
free(c); c = __a;
}

On ne peut absolument rien dire sur ce code. Son comportement est
entièrement dépendant du compilateur, car tous les identificateur s qui
ont un double-souligné sont réservé pour le compilateur, et ils peuvent
signifier n'importe quoi.
En enlevant les doubles soulignés et en effectuant les corrections
évidentes nécessaires à une compilation sans erreur, ça marche
parfaitement:
-*- mode: compilation; default-directory: "/tmp/" -*-
Compilation started at Wed May 30 23:45:59
SRC="/tmp/f.c" ; EXE="f" ; LINE=--------------------; echo ${LINE};ca t ${SRC} ;echo ${LINE}; gcc -I. -L. -g3 -ggdb3 -o ${EXE} ${SRC} && ./${EXE } && echo status = $?
--------------------
#include <stdlib.h>
#include <string.h>
typedef struct {
} struct_processus;
typedef long int integer8;
#define unused(x) ((void)x)
unsigned char * formateur_flux(struct_processus *s_etat_processus, unsigned char *donnees,
integer8 *longueur){
unused(s_etat_processus),unused(donnees);
*longueur=3;
return (unsigned char*)"foo";
}
unsigned char* f(){
unsigned char *a; integer8 l;
struct_processus s_etat_processus;
unsigned char* c=(unsigned char*)strdup("bar");
a = formateur_flux(&s_etat_processus, c, &l);
if (a == NULL) return NULL;
free(c); c = a;
return c;
}
int main(){
f();
return 0;
}
--------------------
status = 0
Compilation finished at Wed May 30 23:45:59
et je me prends :
ngspice.rplc: In function ‘__external_loadCircuit’:
ngspice.rplc:160:9: warning: assignment makes pointer from integer withou t 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 sig nedness [-Wpointer-sign]
free(c); c = __a;
^
J'ai beau regarder dans tous les sens. c est un unsigned char *.
__a aussi.

Non, tu ne peux pas dire ça. Peut être que pour ton compilateur, __
veut dire: signale une erreur de type pour faire chier.
formateur_flux() renvoie un unsigned char *. Pourquoi
cette affectation pose-t-elle problème ?
Je sèche lamentablement.
Bien cordialement,
JKB

--
__Pascal J. Bourguignon
http://www.informatimago.com
Avatar
espie
In article ,
JKB wrote:
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

Montre le code post-preprocesseur, pour commencer.
__a, c'est quand meme violemment dans l'espace reserve pour le systeme.
T'es sur que t'as pas une macro ou une autre declaration qui cacherait
la tienne ?
Et aussi le vrai code, pas juste des fragments.
Tu connais le principe de la dichotomie pour converger sur la sequence
qui pose probleme, n'est-ce pas ? Donc tu commences par le preprocesseur...
puis si t'as pas trouve, tu reduis ton code a une sequence plus courte
qui pose le meme souci, et que tu pourras nous montrer en integralite.
Avatar
JKB
Le Wed, 30 May 2018 23:44:16 +0200,
Olivier Miakinen <om+ écrivait :
Le 30/05/2018 18:17, JKB a écrit :
Rhoh pétard. Je me filerais des baffes !
Début de mon fichier de macros de programmation :
#ifndef INCLUSION_RPLARGS
# define INCLUSION_RPLARGS
/*
=============================================================================== >> INCLUSIONS
=============================================================================== >> */
// Si TYPE_DECLARATION est défini, toutes les structures internes du RPL/2
// sont exposés pour travailler sur des nouveaux types de données.
# ifndef TYPE_DECLARATION
# define RPLARGS
# define struct_processus void
# endif
# include "rpl.h"
Note bien le define RPLARGS (puisque TYPE_DECLARATION n'est pas
défini). Et dans mes prototypes :
#ifndef RPLARGS
...
unsigned char *formateur_flux(struct_processus *s_etat_processus,
unsigned char *donnees, integer8 *longueur);
...
#endif

Ah oui, je comprends que ce soit difficile à lire et source d'erreur,
ce #define qui dépend d'un #ifndef avec un autre nom.
Pour ma part, autant que possible j'essaye que mes #include soient
inconditionnels (donc pas dans un #if ... #endif), et ils ressemblent
à ça :
--------------------------------------
/*
* Fichier foo.h
*/
#ifndef _FOO_H
#define _FOO_H
...
...
...
#endif /* _FOO_H */
--------------------------------------
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.
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
Avatar
Lucas Levrel
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 ?
--
LL
Ἕν οἶδα ὅτι οὐδὲν οἶδα (Σωκράτης)
1 2