2

given the following code:

/* 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 */

I see that the constness is the problem, but I don't know why or how to avoid it. What I want is a function which can't modify the params anymore. Any advice is welcome(besides disabling this warning or deleting const in the processing function).

Thanks: Visko

leppie
  • 115,091
  • 17
  • 196
  • 297
Visko
  • 23
  • 2

3 Answers3

2

You can't eliminate these warnings in C without making an explicit cast to the proper type. Without a typedef this is going to look ugly though

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

This is a strange quirk specific to C language. In C++ this issue was fixed.

BTW, the {} initializer is illegal in C. How did you manage to get that to compile?

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Thanks, with a #define param_const_t const char (*)[MAX_LINE_LEN] it's not that ugly. It's just non-sense to me why this strictness increasing "casting" causes warning. – Visko Jun 21 '10 at 09:11
  • I've been using the {} initializer for a while. I'm using gcc, but I had no problem with visual studio's compiler. Now that you mentioned, I tried with cadul compiler (which is so ANSI standard that it wouldn't accept // as comment) and it fails. Another non-sense thing... – Visko Jun 21 '10 at 09:31
  • @Visko: AFAIK, Visual Studio won't accept it either, assuming you are compiling as C, not as C++. And your question is tagged C. – AnT stands with Russia Jun 21 '10 at 09:49
  • @Visko: I believe it's related to this entry in the C FAQ: http://c-faq.com/ansi/constmismatch.html , although it's not identical and this *particular* case should be fine. – caf Jun 21 '10 at 13:57
  • @Visko: you have to distinguish different versions of norms for C. For C99 the initializer has you gave it is no good, you'd have to write { 0 }. But // for comments is allowed, there. Best is probably to tell the compiler which norm you want to follow and then to stick to it. – Jens Gustedt Jun 21 '10 at 15:10
1

There is no good solution to this problem - I usually just comment out the const qualifier on the function parameter to show that it should ideally be const but that we also want to compile without warnings, i.e.

int getVersion(/* const */ char params[MAX_PARAM_LEN][MAX_LINE_LEN],
               const char* tagName );
Paul R
  • 208,748
  • 37
  • 389
  • 560
  • But then if you pass a `const char[][MAX_LINE_LEN]` to it, you'll get a warning! Isn't there any type that can take both `char [][N]` and `const char [][N]` without warning? – Shahbaz Jun 19 '12 at 08:56
  • @Shabhaz: if you find a way then please let me know - with C it seems you have to pick one (const or non-const) and then be prepared to cast when passing the "wrong" type. Usually you will be passing non-const arrays (in my experience at least), hence the above recommendation. – Paul R Jun 19 '12 at 09:09
  • Yeah, it is kind of annoying. Anyway, I'm fine without `const`. It's kind of useless anyway – Shahbaz Jun 19 '12 at 09:18
  • `const` can be useful for catching logic bugs and potentially for compiler optimisations too - but in this case it's probably more trouble than it's worth. – Paul R Jun 19 '12 at 09:24
0
foo((char const (*)[MAX_LINE_LEN] params);

works but is not very practical and could be dangerous (it accepts any pointer).

A more robust way would be:

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

You can automate this "casting" using the macro P99_ACALL, see http://gustedt.wordpress.com/2011/02/12/const-and-arrays/ for more details.

Mathieu Delmeau
  • 306
  • 1
  • 6