简体   繁体   English

这也是Ansi C中未定义的行为吗?

[英]Is this also an undefined behavior in Ansi C?

If the code like this, it must be an undefined behavior . 如果这样的代码,则必须是undefined behavior

char *String = "Stack Overflow"; //undefined behavior

For this reason, is the following also an undefined behavior? 因此,以下行为也是未定义的行为吗? But most of my reference book write like this! 但是我的大多数参考书都是这样写的!

char *Print (char *String)
{
    return String;
}

int main (void)
{
    printf ("%s", Print("Stack Overflow"));
    return 0;
}

To avoid writing an undefined-behavior code, why not doing like this? 为了避免编写行为未定义的代码,为什么不这样做呢?

char *Print (char String[16])
{
    return String;
}

int main (void)
{
    printf ("%s", Print("Stack Overflow"));
    return 0;
}

If the code like this, it must be an undefined behavior. 如果这样的代码,则必须是未定义的行为。

 char *String = "Stack Overflow"; //undefined behavior 

Must be? 一定是? Why? 为什么? No, it isn't. 不,不是。 Perhaps it's not the best idea to assign a string literal to a pointer-to-non- const , but as long as you don't modify its contents, it's OK. 将字符串文字分配给指向非const的指针也许不是最好的主意,但是只要您不修改其内容,就可以了。

The second construct isn't undefined either. 第二种构造也不是未定义的。 String literals have static storage duration. 字符串文字具有静态存储期限。 If you return a pointer to the first character to it, it will be valid regardless of the lifetime and scope of the pointer (as long as it's copied over properly, eg it's passed to or returned from a function, which is exactly what happens in your code). 如果您返回指向第一个字符的指针,则无论指针的有效期和范围如何,该指针均有效(只要正确地复制了该指针,例如,将其传递给函数或从函数返回,这正是在您的代码)。

Defining a string like this is not an undefined behaviour. 定义这样的字符串不是未定义的行为。 What will occur when you write, 当您写作时会发生什么,

char *String = "Stack Overflow";

if that the compiler will reserve an array of bytes in the data segment of the executable and put the "Stack Overflow" string there. 如果编译器将在可执行文件的数据段中保留字节数组,然后将“ Stack Overflow”字符串放在此处。 Then it will point the String pointer at it. 然后它将String指针指向它。 It is only when you attempt to access this pointer the behaviour will be undefined. 仅当您尝试访问此指针时,行为才是未定义的。

Note that overall it is better to avoid the additional indirection and simply define: 请注意,总体上最好避免附加的间接访问,而只需定义:

static const char String[] = "Stack Overflow";

The difference is subtle, but you save on a pointer and you also tell the compiler that String is immutable and it will likely be placed in a readonly memory page. 差别很细微,但是您保存了一个指针,并且还告诉编译器String是不可变的,它很可能会放置在只读内存页中。

After your recent edit, it seems you are concerned that all the characters in a string literal -- ie an array of characters -- are pushed onto the stack for a function call. 最近进行编辑后,似乎您担心将字符串文字中的所有字符(即,字符数组)都压入堆栈以进行函数调用。 This is incorrect. 这是不正确的。 Only a pointer to the array is passed and pointers to string literals -- or any string for that matter -- are always the same size and known to the compiler at compile time. 仅传递指向数组的指针,并且指向字符串文字的指针(或与此相关的任何字符串)始终具有相同的大小,并且在编译时为编译器所知。

As for your first example, it does not have any undefined behavior. 对于第一个示例,它没有任何未定义的行为。 The string literal -- the text between the quotes -- is written into an array of characters by the compiler. 字符串文字(引号之间的文本)由编译器写入字符数组。 Then a pointer -- ie the "address" of the array -- is assigned to the varible correctly declared to be a char * -- though const char * or const char * const may be more appropriate depending on implementation details and programmer intent. 然后,将一个指针(即数组的“地址”)分配给正确声明为char *的变量-尽管const char *const char * const可能更合适,具体取决于实现细节和程序员的意图。

Attempting to modify the contents of the String variable is undefined. 尝试修改 String变量的内容是未定义的。

The use of char* , passing it as a parameter and returning it from the function are not UB. 使用char* ,将其作为参数传递并从函数返回不是UB。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM