[英]Can memcpy or memmove return a different pointer than dest?
The function memmove
is defined like this: 函数
memmove
定义如下:
void *memmove(void *dest, const void *src, size_t n);
In the Linux manual page, it says: 在Linux手册页中,它说:
RETURN VALUE
返回值
The memmove() function returns a pointer to dest.memmove()函数返回指向dest的指针。
Why isn't the function just defined as void memmove(…)
when it always returns one of the input parameters? 当函数总是返回其中一个输入参数时,为什么函数只被定义为
void memmove(…)
? Can the return value be different from dest
? 返回值可以与
dest
不同吗?
Or is the return value really always dest
and it is just done to be able to compose the function in some creative ways? 或者是返回值真的总是
dest
,它只是做是为了能够撰写的功能在一些创造性的方式?
memmove
will never return anything other than dest
. memmove
永远不会返回除dest
之外的任何东西。
Returning dest
, as opposed to making memmove
void, is useful when the first argument is a computed expression, because it lets you avoid computing the same value upfront, and storing it in a variable. 当第一个参数是计算表达式时,返回
dest
而不是使memmove
void是有用的,因为它允许您避免先前计算相同的值,并将其存储在变量中。 This lets you do in a single line 这使您可以在一行中完成
void *dest = memmove(&buf[offset] + copiedSoFar, src + offset, sizeof(buf)-offset-copiedSoFar);
what you would otherwise need to do on two lines: 你需要在两行上做什么:
void *dest = &buf[offset] + copiedSoFar;
memmove(dest, src + offset, sizeof(buf)-offset-copiedSoFar);
As per C11
, chapter §7.24.2.1 and §7.24.2.2 根据
C11
,章节§7.24.2.1和§7.24.2.2
void *memcpy(void * restrict s1, const void * restrict s2, size_t n);
[...] The
memcpy
function returns the value ofs1
.[...]
memcpy
函数返回s1
的值。
and, 和,
void *memmove(void *s1, const void *s2, size_t n);
[...] The
memmove
function returns the value ofs1
.[...]
memmove
函数返回s1
的值。
So, the functions will always return the pointer to the destination buffer, that's by design. 因此,函数将始终返回指向目标缓冲区的指针,这是设计的。
Now coming to the why part, many functions are designed this way to make chaining of function calls possible. 现在来到为什么部分,许多函数都是这样设计的,以使函数调用链接成为可能。 That way, you can have a call to
memmove()
as an argument to another function, where the copied value ( ie, the pointer to dest
) is going to be of some use. 这样,您可以调用
memmove()
作为另一个函数的参数,其中复制的值( 即指向dest
的指针 )将会有一些用处。
For example, you can write the shorter one 例如,您可以编写较短的一个
puts(memmove(dest_buffer, src_buffer, welcome_message_size));
instead of the longer one 而不是更长的一个
memmove(dest_buffer, src_buffer, welcome_message_size);
puts(dest_buffer);
The idiom of returning the exact value of one of the arguments (of pointer type) exists in order to support "chained" function calls (also see strcpy
, strcat
etc). 返回其中一个参数(指针类型)的确切值的习惯用法是为了支持“链式”函数调用(也见
strcpy
, strcat
等)。 It allows you to write some repetitive code as a single expression statement instead of splitting it into multiple statements. 它允许您将一些重复代码编写为单个表达式语句,而不是将其拆分为多个语句。 For example
例如
char buffer[1024];
printf("%s\n", strcat(strcat(strcpy(buffer, "Hello"), " "), "World"));
struct UserData data_copy;
some_function(memcpy(&data_copy, &original_data, sizeof original_data));
Even if you don't like this style of organizing code and prefer doing the same through multiple statements, the overhead of returning an [unnecessary] pointer value is virtually non-existent. 即使您不喜欢这种组织代码的方式并且更喜欢通过多个语句执行相同的操作,返回[不必要的]指针值的开销几乎不存在。
One can even say that the value of this idiom increased a bit after the introduction of compound literals in C99. 甚至可以说,在C99中引入复合文字后,这个习语的价值有所增加。 With compound lterals this very idiom allows one to write the same code without introducing a named intermediate variable
使用复合lterals这个非常成语允许人们在不引入命名中间变量的情况下编写相同的代码
printf("%s\n", strcat(strcat(strcpy((char [1024]) { 0 }, "Hello"), " "), "World!"));
some_function(memcpy(&(struct UserData) { 0 }, &original_data, sizeof original_data));
which makes sense since in most cases that named variable is supposed to be short-lived, is not needed afterwards, and only clutters the namespace. 这是有道理的,因为在大多数情况下,命名变量应该是短命的,之后不需要,并且只会混淆命名空间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.