“终身" C中的字符串文字 [英] "Life-time" of a string literal in C

查看:135
本文介绍了“终身" C中的字符串文字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下函数返回的指针是否不可访问?

Wouldn't the pointer returned by the following function be inaccessible?

char *foo(int rc)
{
    switch (rc)
    {
        case 1:

            return("one");

        case 2:

            return("two");

        default:

            return("whatever");
    }
}

因此,C/C ++中的局部变量的生存期实际上仅在函数内,对吗?这意味着char* foo(int)终止后,它返回的指针不再意味着什么,对吧?

So the lifetime of a local variable in C/C++ is practically only within the function, right? Which means, after char* foo(int) terminates, the pointer it returns no longer means anything, right?

我对局部变量的生存期感到困惑.什么是好的澄清?

I'm a bit confused about the lifetime of a local variable. What is a good clarification?

推荐答案

是的,局部变量的生存期在创建它的范围({})之内.

Yes, lifetime of a local variable is within the scope({,}) in which it is created.

局部变量具有自动或局部存储. 自动,因为一旦它们的创建范围结束,它们就会被自动销毁.

Local variables have automatic or local storage. Automatic because they are automatically destroyed once the scope within which they are created ends.

但是,您这里拥有的是字符串文字,它在实现定义的只读内存中分配.字符串文字与局部变量不同,它们在程序的整个生命周期中都保持有效.它们具有静态持续时间 [Ref 1] 生存期.

However, What you have here is an string literal, which is allocated in an implementation defined read-only memory. String literals are different from local variables and they remain alive throughout the program lifetime. They have static duration [Ref 1] lifetime.

请注意!

但是,请注意,任何尝试修改字符串文字内容的尝试都是未定义的行为(UB).用户程序不允许修改字符串文字的内容.
因此,始终鼓励在声明字符串文字时使用const.

However, note that any attempt to modify the contents of an string literal is an undefined behavior (UB). User programs are not allowed to modify contents of a string literal.
Hence, it is always encouraged to use a const while declaring a string literal.

const char*p = "string"; 

代替

char*p = "string";    

实际上,在C ++中,不推荐在不使用const的情况下声明字符串文字,尽管在C语言中却不这样做.但是,使用const声明字符串文字具有以下优点:编译器通常会在如果您尝试在第二种情况下修改字符串文字.

In fact, in C++ it is deprecated to declare a string literal without the const though not in C. However, declaring a string literal with a const gives you the advantage that compilers would usually give you a warning in case you attempt to modify the string literal in second case.

示例程序:

Sample program:

#include<string.h> 
int main() 
{ 
    char *str1 = "string Literal"; 
    const char *str2 = "string Literal"; 
    char source[]="Sample string"; 

    strcpy(str1,source);    // No warning or error just Uundefined Behavior 
    strcpy(str2,source);    // Compiler issues a warning 

    return 0; 
} 

输出:

cc1:警告被视为错误
prog.c:在"main"函数中:
prog.c:9:错误:传递"strcpy"的参数1会丢弃指针目标类型

cc1: warnings being treated as errors
prog.c: In function ‘main’:
prog.c:9: error: passing argument 1 of ‘strcpy’ discards qualifiers from pointer target type

请注意,编译器会针对第二种情况发出警告,但不会针对第一种情况发出警告.

Notice the compiler warns for the second case, but not for the first.

要在此处回答几个用户提出的问题:

To answer the question being asked by a couple of users here:

整型字面量是什么?

换句话说,以下代码有效吗?

In other words, is the following code valid?

int *foo()
{
    return &(2);
} 

答案是,没有此代码无效.格式不正确,会导致编译器错误.

The answer is, no this code is not valid. It is ill-formed and will give a compiler error.

类似的东西:

prog.c:3: error: lvalue required as unary ‘&’ operand

字符串文字是l值,即:您可以使用字符串文字的地址,但不能更改其内容.
但是,其他任何文字(intfloatchar等)都是r值(C标准对此使用术语表达式的值)及其地址完全不能采取.

String literals are l-values, i.e: You can take the address of an string literal, but cannot change its contents.
However, any other literals (int,float,char, etc.) are r-values (the C standard uses the term the value of an expression for these) and their address cannot be taken at all.

[参考1] C99标准6.4.5/5字符串文字-语义":

在翻译阶段7中,一个或多个字符串文字产生的每个多字节字符序列将附加一个零值的字节或代码. 然后,将多字节字符序列用于初始化一个足以包含该序列的静态存储持续时间和长度数组.对于字符串文字,数组元素的类型为char,并使用多字节字符序列的各个字节进行初始化.对于宽字符串文字,数组元素的类型为wchar_t,并使用宽字符序列进行初始化...

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. For character string literals, the array elements have type char, and are initialized with the individual bytes of the multibyte character sequence; for wide string literals, the array elements have type wchar_t, and are initialized with the sequence of wide characters...

如果这些数组的元素具有适当的值,则不确定这些数组是否不同. 如果程序尝试修改此类数组,则行为未定义.

It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

这篇关于“终身" C中的字符串文字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆