2010-06-21 5 views
1

donné le code suivant:Comment éliminer l'avertissement pour passer tableau multidimensionnel comme tableau multidimensionnel const?

/* signatures */ 
int getParams(char params[MAX_PARAM_LEN][MAX_LINE_LEN]); 
int getVersion(const char params[MAX_PARAM_LEN][MAX_LINE_LEN], 
       const char* tagName); 
/* initializing */ 
char params[MAX_PARAM_LEN][MAX_LINE_LEN] = {}; 

/* getting parameters */ 
paramCount = getParams(params); /* OK, params match with getParams signature */ 

/* processing the params array */ 
i = getVersion(params, "version"); /* warning: passing arg 1 of `getVersion' from incompatible pointer type */ 

Je vois que le constness est le problème, mais je ne sais pas pourquoi ou comment l'éviter. Ce que je veux, c'est une fonction qui ne peut plus modifier le params. Tout conseil est le bienvenu (outre la désactivation de cet avertissement ou la suppression de const dans la fonction de traitement).

Merci: Visko

Répondre

2

Vous ne pouvez pas éliminer ces avertissements en C sans faire un casting explicite du type approprié. Sans un typedef cela va sembler moche si

i = getVersion((const char (*)[MAX_LINE_LEN]) params, "version") 

Ceci est une étrange bizarrerie spécifique au langage C. En C++, ce problème a été corrigé.

BTW, l'initialiseur {} est illégal dans C. Comment avez-vous réussi à obtenir que pour compiler?

+0

Merci, avec un #define param_const_t const char (*) [MAX_LINE_LEN] ce n'est pas si moche. C'est juste un non-sens pour moi que cette rigueur croissante "casting" provoque un avertissement. – Visko

+0

J'utilise l'initialiseur {} depuis un moment. J'utilise gcc, mais je n'ai eu aucun problème avec le compilateur de Visual Studio. Maintenant que vous avez mentionné, j'ai essayé avec le compilateur de cadul (qui est si ANSI standard qu'il n'accepterait pas // comme commentaire) et il échoue. Une autre chose non-sens ... – Visko

+0

@Visko: AFAIK, Visual Studio ne l'acceptera pas non plus, en supposant que vous compilez en C, pas en C++. Et votre question est marquée C. – AnT

1

Il n'y a pas de bonne solution à ce problème - En général, je commente le qualificatif const sur le paramètre de fonction pour montrer qu'il devrait idéalement être const mais nous voulons aussi compiler sans avertissement, à savoir

int getVersion(/* const */ char params[MAX_PARAM_LEN][MAX_LINE_LEN], 
       const char* tagName); 
+0

Mais si vous lui passez un 'const char [] [MAX_LINE_LEN]', vous recevrez un avertissement! N'y a-t-il aucun type qui peut prendre à la fois 'char [] [N]' et 'const char [] [N]' sans avertissement? – Shahbaz

+0

@Shabhaz: si vous trouvez un moyen alors s'il vous plaît faites le moi savoir - avec C il semble que vous deviez en choisir un (const ou non-const) et ensuite être prêt à lancer au passage du "mauvais" type. Habituellement, vous passerez des tableaux non-const (dans mon expérience au moins), d'où la recommandation ci-dessus. –

+0

Oui, c'est plutôt ennuyeux. Quoi qu'il en soit, je vais bien sans 'const'.C'est en quelque sorte inutile de toute façon – Shahbaz

0
foo((char const (*)[MAX_LINE_LEN] params); 

fonctionne mais n'est pas très pratique et pourrait être dangereux (il accepte n'importe quel pointeur).

Une façon plus robuste serait:

foo((char const(*)[MAX_LINE_LEN])(char const*const){ &params[0][0] }); 

Vous pouvez automatiser cette « coulée » en utilisant la macro P99_ACALL, voir http://gustedt.wordpress.com/2011/02/12/const-and-arrays/ pour plus de détails.