OVH Cloud OVH Cloud

Super debutant

85 réponses
Avatar
Albert
Bonjour a tous,
Voila je commence le C sur linux ( RH 9 - gcc gcc (GCC) 3.2.2 20030222
(Red Hat Linux 3.2.2-5)
Je fais le prg le + simple possible :

main()
{
int a = 17 , b = 36;
printf("%d\n, a * b );
}
a la compile j'obtients :
[gil@P4LX gil]$ cc -c test.c
test.c:1: erreur d'analyse syntaxique avant « buffer »
test.c:1:36: caractère ' de terminaison manquant
test.c:1:36: AVERTISSEMENT: constante caractère trop longue
test.c:2: erreur d'analyse syntaxique avant « you »
test.c:2: erreur d'analyse syntaxique avant « that »
test.c:3: erreur d'analyse syntaxique avant « enter »
test.c:3:36: caractère ' de terminaison manquant
test.c:3:36: AVERTISSEMENT: constante caractère trop longue
test.c:7:10: AVERTISSEMENT: chaîne de mots multi-lignes sont dépréciés
test.c:7:10: caractère " de terminaison manquant
test.c:7:10: début possible d'une chaîne de mot non terminée
test.c:7: erreur d'analyse syntaxique avant la constante chaîne
[

J'avoue avoir beaucoup (trop) oublie le C quand j'etait jeune mais la je
ne comprends pas. Ne vous moquez pas trop !!

Merci pour les reponses.
gilles

5 réponses

5 6 7 8 9
Avatar
Pierre Maurette
[...]
NB: Alors la je dis bravo !!! . Avec un petit Gamay leger ??
Un gamay est très souvent petit et "sans prétention". Et toujours léger

et "gouleyant". Ça, c'est ce qui se dit. Personnellement, quand un
gamay est léger, je dis "aégalous", c'est à dire en gros "à goût de
flotte".

La règle veut que les noms de vins, cépage ou région, s'écrivent avec
une minuscule initiale. Ce sera donc "un bourgogne vraiment élevé en
Bourgogne", "un beaujolais", etc. J'imagine qu'on écrira "un touraine",
mais "un gamay de Touraine", voire "un gamay du Beaujolais" ?

Santé ...

--
Pierre Maurette

Avatar
Charlie Gordon
"Antoine Leca" wrote in message
news:dkaud1$j7v$
[snip]
C99 oblige à avoir une déclaration pour chaque fonction utilisée, mais ce
peut être une déclaration ancien format ; genre

#if __STDC_VERSION__-0 <199711L
#define restrict
#endif
int main(argc, argv) int argc; char *argv[]; {
extern int atoi(), printf(char const * restrict, ...);

if(argc>1) printf("%dn", atoi(*++argv));
return 0;
}


Quelqu'un pourrait-il m'expliquer l'intérêt du mot-clé restrict dans une
déclaration externe ? ni le programmeur ni le compilateur ne peuvent tirer
d'information utile de cette indication dans un prototype. Par exemple la
déclaration de memcpy() utilise restrict pour les pointeurs source et
destination:

extern void *memcpy(void * restrict __dest, const void * restrict __src, size_t
__n);

et la documentation précise la contrainte que les zones de source et destination
de la copie doivent être disjointes, le mot-clé restrict ne suffit pas au
compilateur à exprimer cette contrainte, et il est même possible d'invoquer
memcpy avec un pointeur identique pour source et destination et une taille
nulle.

Cela me semble totalement sans intérêt, un peu comme il serait vain de déclarer
les paramètres const comme ceci :

int exit(int const exit_code);

Pas beau (du tout du tout), mais légal sauf erreur de ma part.
Le "return 0;" est là pour la compatibilité C90.


C'est une ignominie que C99 tolère son oubli !

--
Chqrlie.

Avatar
Richard Delorme
"Antoine Leca" wrote in message
news:dkaud1$j7v$
[snip]

C99 oblige à avoir une déclaration pour chaque fonction utilisée, mais ce
peut être une déclaration ancien format ; genre

#if __STDC_VERSION__-0 <199711L
#define restrict
#endif
int main(argc, argv) int argc; char *argv[]; {
extern int atoi(), printf(char const * restrict, ...);

if(argc>1) printf("%dn", atoi(*++argv));
return 0;
}



Quelqu'un pourrait-il m'expliquer l'intérêt du mot-clé restrict dans une
déclaration externe ? ni le programmeur ni le compilateur ne peuvent tirer
d'information utile de cette indication dans un prototype. Par exemple la
déclaration de memcpy() utilise restrict pour les pointeurs source et
destination:

extern void *memcpy(void * restrict __dest, const void * restrict __src, size_t
__n);

et la documentation précise la contrainte que les zones de source et destination
de la copie doivent être disjointes, le mot-clé restrict ne suffit pas au
compilateur à exprimer cette contrainte, et il est même possible d'invoquer
memcpy avec un pointeur identique pour source et destination et une taille
nulle.


Je ne pense pas que restrict soit là pour que le compilateur vérifie
cette contrainte des zones mémoires disjointes, mais au contraire pour
lui assurer que cette contrainte est vérifiée sans qu'il ait à s'en
préoccuper. Pour le programmeur, la présence du mot clé restrict est
relativement importante, puisque c'est à lui de s'assurer que les
données ne se chevauchent pas.
Pour plus de détail, Cf :
http://www.lysator.liu.se/c/restrict.html

En résumé, restrict est là pour simplifier la vie du compilateur et
embêter le programmeur, ce qui est une drôle de philosophie, qui
explique sans doute le coût de colère de D. Ritchie quand noalias (la
version initiale de restrict pour C90) a été proposée :
http://www.lysator.liu.se/c/dmr-on-noalias.html


Cela me semble totalement sans intérêt, un peu comme il serait vain de déclarer
les paramètres const comme ceci :

int exit(int const exit_code);


Là, la situation est presque pire, puisque cela n'apporte aucune
information importante pour le programmeur. D'un autre côté, cela ne
coûte pas grand chose de préciser les qualificateurs dans une déclaration.



--
Richard


Avatar
Antoine Leca
En news:4369cde6$0$7341$,
Charlie Gordon va escriure:
Antoine Leca wrote in news:dkaud1$j7v$
[snip]
#if __STDC_VERSION__-0 <199711L
#define restrict
#endif
extern int atoi(), printf(char const * restrict, ...);


Quelqu'un pourrait-il m'expliquer l'intérêt du mot-clé restrict dans
une déclaration externe ?


Il n'y a aucune différence entre /const/ et /restrict/. Si la déclaration
officielle a un /restrict/, tu es obligé de le remettre quand tu recopies le
prototype, par exemple si un petit malin essaye de passer comme argument un
/restrict char * p/ ...


ni le programmeur ni le compilateur ne peuvent tirer d'information
utile de cette indication dans un prototype.


Ici non, mais de manière plus générale si, si tu appelles une fonction en
ayant comme paramètre des pointeurs restreints.


Par exemple la déclaration de memcpy() utilise restrict
pour les pointeurs source et destination:


C'est toute la différence entre /memcpy()/ et /memmove()/.


extern void *memcpy(void * restrict __dest, const void * restrict
__src, size_t __n);

et la documentation précise la contrainte que les zones de source et
destination de la copie doivent être disjointes, le mot-clé restrict
ne suffit pas au compilateur à exprimer cette contrainte,


Certes, /restrict/ n'est pas suffisant en général.

et il est même possible d'invoquer memcpy avec un pointeur identique
pour source et destination et une taille nulle.


Oui. Et alors ? C'est permis (avec une lecture pas complètement évidente)
par la description de /strcpy()/, et c'est compatible avec /restrict/. Où
est le problème ?


Antoine


Avatar
Antoine Leca
En news:,
Etienne de Tocqueville va escriure:
Emmanuel Delahaye writes:

Si. printf() est une fonction variadic f(T param, ...). Le prototype
est *obligatoire*.


Et pourquoi est-ce obligatoire ? Tu aurais un exemple de petit bout de
code où printf ne fonctionne pas sans le prototype ?


Sur n'importe quelle architecture pour laquelle la convention de passage des
arguments variadiques est différente de la normale, tu auras un problème.

Alors bien sûr, la quasi-totalité des compilateurs confrontés à ce problème
font un cas spécial pour printf(), qu'ils repèrent spécifiquement par son
nom, un peu comme main(). Donc il est TRÈS difficile de fournir un exemple
de non-fonctionnement.
Mais la norme ne fait pas d'exception pour printf(), et résoud le problème
général en obligeant les fonctions variadiques à être déclarées avec
prototypes.


Ou alors ça dépend de l'architecture de la machine ou du compilateur ?...


Oui.
Je pense qu'avec le cas classique du passage de paramètres sur la pile en
commençant par pousser les derniers et dépilage par l'appelant, il est
impossible que cela ne marche pas.


Antoine


5 6 7 8 9