Thread: Why compiler warning?

  1. #16
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Quote Originally Posted by comp.lang.c
    Re: Incompatible pointer type question

    The only person I know who can make sense of this stuff
    (i.e. distill the discussions on this topic in comp.std.c
    down to language which mere mortals can understand) is Tanmoy
    Bhattacharya. Here's the book's version of question 11.10,
    much of which basically paraphrases a message Tanmoy once sent me:

    11.10: Why can't I pass a char ** to a function which expects a
    const char **?

    A: You can use a pointer-to-T (for any type T) where a pointer-to-
    const-T is expected. However, the rule (an explicit exception)
    which permits slight mismatches in qualified pointer types
    is not applied recursively, but only at the top level.
    (const char ** is pointer-to-pointer-to-const-char, and the
    exception therefore does not apply.)

    The reason that you cannot assign a char ** value to a
    const char ** pointer is somewhat obscure. Given that the
    const qualifier exists at all, the compiler would like to help
    you keep your promises not to modify const values. That's why
    you can assign a char * to a const char *, but not the other
    way around: it's clearly safe to "add" const-ness to a simple
    pointer, but it would be dangerous to take it away. However,
    suppose you performed the following more complicated series of
    assignments:
    Code:
      const char c = 'x';  /* 1 */
      char *p1;   /* 2 */
      const char **p2 = &p1;  /* 3 */
      *p2 = &c;   /* 4 */
      *p1 = 'X';   /* 5 */
    In line 3, we assign a char ** to a const char **. (The
    compiler should complain.) In line 4, we assign a const char *
    to a const char *; this is clearly legal. In line 5, we modify
    what a char * points to -- this is supposed to be legal.
    However, p1 ends up pointing to c, which is const. This came
    about in line 4, because *p2 was really p1. This was set up
    in line 3, which is an assignment of a form that is disallowed,
    and this is exactly *why* line 3 is disallowed.

    Assigning a char ** to a const char ** (as in line 3, and in the
    original question) is not immediately dangerous. But it sets up
    a situation in which p2's promise -- that the ultimately-pointed-
    to value won't be modified -- cannot be kept.

    (C++ has more complicated rules for assigning const-qualified
    pointers which let you make more kinds of assignments without
    incurring warnings, but still protect against inadvertent
    attempts to modify const values. C++ would still not allow
    assigning a char ** to a const char **, but it would let you
    get away with assigning a char ** to a const char * const *.)

    In C, you must use explicit casts (e.g. (const char **) in this
    case) when assigning (or passing) pointers which have qualifier
    mismatches at other than the first level of indirection.

    References: ANSI Sec. 3.1.2.6, Sec. 3.3.16.1, Sec. 3.5.3
    ISO Sec. 6.1.2.6, Sec. 6.3.16.1, Sec. 6.5.3
    H&S Sec. 7.9.1 pp. 221-2
    Editor's note: MSVC (and probably other compilers) will compile the given code without warning, even on the highest warning level. Therefore, the const protection is silently broken, even without a cast.

    C FAQ Question 11.10
    Last edited by anonytmouse; 09-06-2004 at 01:12 AM.

  2. #17
    Registered User
    Join Date
    Aug 2003
    Posts
    470
    Well, I know what the term means in C++. In C the meaning, I'm afraid, is supposed to be different. I've never bothered to figure out the exact difference, though.

    I'll try give a brief explanation of why I think I'm right. There really is no such thing as multi-dimensional arrays in C. Arrays of arrays but not multi-dimensional arrays. For the language standard to make this kind of distinction, would breaka little of the structure of the language, by making a special distinction between multidimensional arrays and ordinary objects.

    Doing either of these suggestions, you've given above, would result in correct code. Often, however, people don't like to work with multidimensional arrays, preferring instead to write code such as
    Code:
    typedef struct M {
           int A[100][100];
    };
    or write code using a single array.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. added start menu crashes game
    By avgprogamerjoe in forum Game Programming
    Replies: 6
    Last Post: 08-29-2007, 01:30 PM
  2. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  3. compiler warning message
    By alice in forum C Programming
    Replies: 2
    Last Post: 04-18-2004, 12:53 PM
  4. bcc32 compiler warning when assigning null to pointer
    By finnepower in forum C++ Programming
    Replies: 4
    Last Post: 06-25-2002, 11:37 AM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM