5

I found code in libcurl that looks like:

const char * curl_easy_strerror(CURLcode error) { switch(error) { case CURLE_OK: return "No error"; case CURLE_UNSUPPORTED_PROTOCOL: return "Unsupported protocol"; ..... } 

As I know, if you want to return a pointer, you need to make sure the memory which the pointer point will not be changed or released. Why is it that this libcurl code works?

4
  • 2
    If you want to return a pointer, you need to make sure it will point to something valid after you return it. malloc is one way to do that, but hardly the only way. Commented May 17, 2019 at 3:26
  • 1
    Pointer to a static, global or as in this case a literal constant are also valid. Commented May 17, 2019 at 5:36
  • The answer you selected is incorrect. @P_J_ provided you a correct answer in comments. Commented May 17, 2019 at 7:51
  • Thanks all, this question is duplicated. Add the answer is almost clear after so many useful discusstions. Sting literals is storaged at a special "readonly&static" zone at most time, of course this depends on platform. And the static part is certain(readonly is not certain). Commented May 17, 2019 at 12:53

2 Answers 2

10

Those string literals are placed in a static read-only section of the executable at compile time. They are separate from the heap or the stack. The function is simply returning a pointer that points to those strings.

Reference

The implementation of this is platform and compiler specific, but the C11 standard has a few relevant requirements on this in section 6.4.5.

In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals. The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence.

So we know it must be stored in a static location at compile time.

If the program attempts to modify such an array, the behavior is undefined.

This tells us the data must be read-only.

Edit

Some people are complaining that this is incorrect, citing specific platforms or architectures. As noted above this is platform and compiler specific.

Some platforms, may not support read-only data, but the compiler will almost certainly try to prevent you from modifying it. Since the behavior is undefined, the intent is that you never do this, so for all intents and purposes the data is read-only.

In the context of the question, this answer is correct.

Sign up to request clarification or add additional context in comments.

11 Comments

thanks, it seems c is just like java, string literals is special.
Yeah most languages seem to have at least a few special behaviors for strings.
this is a very bad imprecise answer just repearing the myths about the string literal. string literals do not have to be placed in the RO memory and they do not have to be valid outside the scope they are used. any Harvard architecture computer will copy it first to the data memory. the popular example is the AVR family of the uCs. very popular family used for example in the Arduino boards.
the last sentence is also wrong. it only says that we cannot modify it. if we do modify it,the program behaviour is not defined. Nothing more. your quite naive interpretation of the standard document is wrong
This answer is correct where it matters the most: static storage duration is guaranteed and user must treat literals as read-only. All section stuff and stack/heap stuff is implementation defined and not that relevant to answer actually. I would maybe use little different wording, but overall the answer is fine.
|
4

According to the C standard (6.4.5 String literals, paragraph 6), string literals have static storage duration:

a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals. The multibyte character sequence is then used to initialize an array of static storage duration […]

This means that their memory, wherever it may physically be, is guaranteed to outlive the function return, and pointers to this memory remain valid.

Therefore, you’re returning a pointer to a memory location that’s guaranteed to be valid, and that contains the value given by the string literal.

7 Comments

the problem here is that we are talking in this thread that one cannot find an explicit statement that asserts what you say. Can you paste the explicit statement from ISO9899 that states what you say ?
@alinsoar Added the quote although I believe that it adds zero value to this answer: Finding this quote based on the reference I gave is trivial. Furthermore, the highest-voted answer already contained that exact quote (although I only saw that now, and that answer also contains mistakes).
I saw that statement in ISO9899, I am not sure that used to initialize an array of static storage duration is correctly interpreted as "to keep the string in static zone".
@alinsoar What other way is there to interpret it? It literally says it there. If you saw a compiler doing something different then the compiler was operating under the as-if rule. But the stack allocation only happens if the compiler can prove that no reference to the memory exists after the function exits.
@alinsoar: Examining assembly code only shows you how a C implementation implemented the code. Due to the C standard’s “as if” rule, compilers are allowed to generate any code that want that as the same results. If that program did not rely on the string existing after a function returned, then the compiler can generate code that has the string only on the stack or as an immediates in instructions, because the result in that program is the same. So the compiler optimized the code for that program. That does not change the semantics specified by the C standard.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.