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

查看:43
本文介绍了“终身"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.

示例程序:

#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
     

字符串文字是左值,即:您可以获取字符串文字的地址,但不能更改其内容.
但是,任何其他文字(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.

[Ref 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天全站免登陆