Why cStringUsingEncoding: returns const char * instead of char *?

lockedscope Source

cStringUsingEncoding: returns a "const char *" despite it is returning a dynamically allocated C string(from it's documentation). So, what is the purpose of const here? We could simply modify the returned C string by casting to char *.

cStringUsingEncoding:

The returned C string is guaranteed to be valid only until either the receiver is freed, or until the current autorelease pool is emptied, whichever occurs first.

I think library is following the common practice of pointer-to-const; it's not expected to be modified or released.

From Objective-C runtime;

const char * object_getClassName(id obj) -- Nothing specified about the returned string.

char * method_copyArgumentType(Method method, unsigned int index) -- You must free the string with free(). (May be it's advising because of it's returning a copy.)

objective-ccpointersconst

Answers

answered 5 years ago Christian Stieber #1

Thing is, the result is const because

  • modifying it will not change the string itself, and the cString is really just meant to be a different representation of the string
  • it will probably return the same cString "over and over again", as long as the string doesn't change.

Other than that, declaring a result to be const even if the implementation doesn't enforce or require that is something an interface designer can do, maybe because he wants it to be treated that way. And it leaves the path open to optimize things for cases where the "const" is useful.

answered 5 years ago Matt Wilding #2

The common pattern is that you should not modify buffers that you don't own. const documents and (somewhat) enforces this.

As for cStringUsingEncoding:, The documentation is saying that the returned buffer is only valid as long as the NSString from which you received it, or for the duration of the current autorelease pool. This implies that you do not own the returned buffer, because you're not expected to release it.

Your last two examples from the runtime follow the same convention:

  • const char * object_getClassName(id obj)

    Doesn't inform you that you should release the buffer, and the name doesn't contain any indication that you own the buffer. Therefore you don't free() it, and you don't modify it.

  • char * method_copyArgumentType(Method method, unsigned int index)

    The docs explicitly tell you that you should free the buffer, and the function name contains the tell-tale copy which also implies that you own the buffer. Therefore you can modify it all you want, and must free() it.

comments powered by Disqus