Type of a string literal

S

s0suk3

Hi,

I've heard that a string literal has type 'char *' (i.e., a pointer to
a char object). But I'm confused as to why this works:

char *GetString(void)
{
return "hello";
}

int main(void)
{
printf("%s\n", GetString());

return 0;
}

And it does print 'hello'. But if the pointer that GetString() returns
points to a local object, wouldn't the buffer be deallocated when the
function returns, thus making the pointer point to nothing? Or does
that mean that a string literal has type 'static char *'? Or more
precisely, 'static const char *'?

Thanks,
Sebastian
 
S

santosh

Hi,

I've heard that a string literal has type 'char *' (i.e., a pointer to
a char object). But I'm confused as to why this works:

A string literal has type array of char, but it automatically is
converted to a pointer to it's first element under most contexts, as is
common for all array types in C.
char *GetString(void)
{
return "hello";
}

int main(void)
{
printf("%s\n", GetString());

return 0;
}

And it does print 'hello'. But if the pointer that GetString() returns
points to a local object, wouldn't the buffer be deallocated when the
function returns, thus making the pointer point to nothing? Or does
that mean that a string literal has type 'static char *'? Or more
precisely, 'static const char *'?

Thanks,
Sebastian

Source code string literals are placed in static arrays. Their type is
of type char or wchar_t and are not qualified with const, but modifying
them invokes undefined behaviour anyway.
 
V

vippstar

Hi,

I've heard that a string literal has type 'char *' (i.e., a pointer to
a char object). But I'm confused as to why this works:

char *GetString(void)
{
return "hello";

}

See 6.4.5 p 5 from n1256.pdf. string literals are immutable and
"replaced" in TP 7 by static storage duration arrays. Their actual
type is char [N] where N is the integer returned by sizeof, or wchar_t
[N] (for wide string literals).
When evaluated, these become char * and wchar_t *.

Notice that GetString lies to the programmer; the returned value
cannot be modified! Unless you document that, your function is
misleading.
 
S

s0suk3

I've heard that a string literal has type 'char *' (i.e., a pointer to
a char object). But I'm confused as to why this works:
char *GetString(void)
{
    return "hello";

See 6.4.5 p 5 from n1256.pdf. string literals are immutable and
"replaced" in TP 7 by static storage duration arrays. Their actual
type is char [N] where N is the integer returned by sizeof, or wchar_t
[N] (for wide string literals).
When evaluated, these become char * and wchar_t *.

Notice that GetString lies to the programmer; the returned value
cannot be modified! Unless you document that, your function is
misleading.

Thanks. As for the last part: would it be good practice to qualify the
function definition with 'const'?
 
B

Ben Bacarisse

I've heard that a string literal has type 'char *' (i.e., a pointer to
a char object). But I'm confused as to why this works:
char *GetString(void)
{
    return "hello";

See 6.4.5 p 5 from n1256.pdf. string literals are immutable and
"replaced" in TP 7 by static storage duration arrays. Their actual
type is char [N] where N is the integer returned by sizeof, or wchar_t
[N] (for wide string literals).
When evaluated, these become char * and wchar_t *.

Notice that GetString lies to the programmer; the returned value
cannot be modified! Unless you document that, your function is
misleading.

Thanks. As for the last part: would it be good practice to qualify the
function definition with 'const'?

Yes, const char *GetString(void); would be better. Technically this
is not qualifying the function type, nor is it even qualifying the
function's return type. It is, as required, saying the function
returns pointer to const qualified char.
 
H

Harald van Dijk

When evaluated, [string literals] become char * and wchar_t *.

I forget how the standard characterized evaluated, but certainly in not
all cases does it become pointers (for instance, sizeof).

The operand of sizeof is not usually evaluated.

It's not about whether string literals are evaluated. As part of a non-
evaluated expression, string literals and other arrays are normally still
converted to pointers in at least one sense.

if (0)
puts("Hello, world!");

Even though the literal will never be evaluated, the compiler should not
complain about an invalid function argument type. In the other direction,
as part of the & operator, string literals are evaluated, but not
converted to pointers.
 
H

Harald van Dijk

Actually, I changed my mind and I will say it doesn't say it. :) Either
way I'm curious about whatever appropriate passage you believe sheds
light on this. Thanks.

The code is valid, because even though the function is never called, the
array-to-pointer conversion ensures the constraint that a function's
arguments are assignment-compatible with its parameters is not violated.
I'm sure you're familiar with this, so I've not looked up where and how
exactly the standard specifies this. If a compiler wants to warn "function
argument of array type, expected pointer", but still continues to compile
the code, it can conform to the standard while relying on the as-if rule,
but it's a horrible idea. For that reason, I claim it should not complain,
but not that it must not complain.
 
S

santosh

Greg said:
Actually, for some reason I saw fputs not puts, which now makes
this a different issue. Ok, so you're saying that because of the
if (0) that the puts call is not evaluated, right? If so, I don't
see how that trumps prototypes, syntax checking, etc.

I suppose the translation phases that do those things never get to see
the function in question.
 
H

Harald van Dijk

[snip]

Ok, so you're saying that because of the if (0) that
the puts call is not evaluated, right?
Right.

If so, I don't see how that
trumps prototypes, syntax checking, etc.

It doesn't. That's my point. The original claim was "When evaluated,
[string literals] become char * and wchar_t *." I am trying to say that
they also become char * and wchar_t *, at least in one sense, when not
evaluated, because that's the only way a compiler can sanely accept the
code.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top