-1

I see it everywhere:

  1. http://www.cplusplus.com/reference/cstdio/printf/ -> printf takes format as const char *fmt rather than char * const fmt.
  2. https://msdn.microsoft.com/en-us/library/e0z9k731.aspx -> strings accepted as const pointers rather than pointer consts.
  3. glShaderSource: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glShaderSource.xhtml -> strings taken as const pointer rather than pointer const.
  4. https://msdn.microsoft.com/en-us/library/windows/desktop/ms645505(v=vs.85).aspx -> messageboxa/messageboxw take const pointer to string rather than pointer to const.

Am I misunderstanding something, or is this just misunderstanding on how to express things in C by api designers?

From my understanding,

  1. const char *a, is a pointer to a char which you cannot change to point to another char.
  2. char * const a is a pointer to a char which you cannot dereference to change value of.
  3. const char * const a is a pointer to a char which you cannot change to point to another char(or the first char of contiguous block containing many chars), AND you cannot change the value of the pointed char by dereference.

Thanks ahead of time.

It appears I got it other way around:

char *elephant = "elephant";
const char *p1 = "wolf";
char * const p2 = "sheep";

int main(int argc, char **argv)
{
    p1 = elephant;
    *p1 = elephant[0]; /* error: assignment of read-only location '*p1' */

    p2 = elephant; /* error: assignment of read-only variable 'p2' */
    *p2 = elephant[0];

    return 0;
}

analogous:

#define ptrto(X) X *
#define readonly(X) X const

char const a = 'a';
const char b = 'b';

readonly(ptrto(char)) p1 = "p1";
ptrto(readonly(char)) p2 = "p2";

int main(int argc, char **argv)
{
    p1 = &a; /* error: assignment of read-only variable 'p1' */
    *p1 = a; 

    p2 = &a; 
    *p2 = a; /* error: assignment of read-only location '*p2' */

    p1 = &b; /* error: assignment of read-only variable 'p1' */
    *p1 = b; 

    p2 = &b; 
    *p2 = b; /* error: assignment of read-only location '*p2' */


    return 0;
}
Dmytro
  • 5,068
  • 4
  • 39
  • 50
  • 3
    You mixed up 1. and 2., they're the other way around. – Quentin Jan 04 '18 at 22:41
  • ill test to be sure. – Dmytro Jan 04 '18 at 22:42
  • 1
    Um.. . `const obj *` and `obj *const` are two completely different things. Why would they use `obj *const` if they need `const obj *`? – AnT stands with Russia Jan 04 '18 at 22:44
  • 2
    Here's a trick to help you: read from right to left. `char * const a;` reads as "a is a const pointer to a char". `const char * a;` is "a is a pointer to a char constant". –  Jan 04 '18 at 22:45
  • `const T *` and `T const *` specify a *pointer to constant `T`*. `T * const` specifies a *constant pointer to `T`*. Most APIs use `const T *` or `T const *` because they're promising they won't change the thing being pointed to. – John Bode Jan 04 '18 at 22:52
  • The reference is [6.7.6.1 Pointer declarators - C11 (draft n1570)](http://port70.net/~nsz/c/c11/n1570.html#6.7.6.1) – David C. Rankin Jan 04 '18 at 23:06

1 Answers1

1

See http://en.cppreference.com/w/c/language/const

const char * == char const * is a pointer to non-modifiable character data.

char * const is a non-modifiable pointer to character data.

CiaPan
  • 9,381
  • 2
  • 21
  • 35
  • (`const char *` == `const char *`) is not true, `char *elephant = "elephant"; const char *p1 = "wolf"; char * const p2 = "sheep"; int main(int argc, char **argv) { p1 = elephant; *p1 = elephant[0]; /* error */ p2 = elephant; /* error */ *p2 = elephant[0]; return 0; }` shows that my compiler treats them differently. – Dmytro Jan 04 '18 at 22:51
  • @Dmitry Please read again. – CiaPan Jan 04 '18 at 23:00
  • *en.cppreference.com* isn't the language standard, [6.7.6.1 Pointer declarators - C11 (draft n1570)](http://port70.net/~nsz/c/c11/n1570.html#6.7.6.1) is (at least the last free draft) – David C. Rankin Jan 04 '18 at 23:08