为什么这段代码有效?常量数组上的 memcpy
Why this code works ? memcpy on a constant array
memcpy
的参数是memcpy(void *_Dst, const void *_Src, size_t _Size)
但是使用下面的代码,我传递了一个常量数组作为参数“_Src”,它仍然将数组的内容复制到目标中,即使我没有传递 const void *
。
int tab[3] = { 1, 2, 3 };
memcpy(tab, (int[3]) { 7, 8, 9 }, sizeof(int) * 3);
printf("%d %d %d \n", tab[0], tab[1], tab[2]); // Output: 7 8 9
表达式 (int[3]) { 7, 8, 9 }
returns 是指向数组第一个元素的指针吗?
当函数的参数声明为指向 const
类型的指针时,它“阻止”函数修改指针指向的内容(即不通过参数本身,但它可以通过强制转换), 但不限制实参类型为const
.
非const
限定类型的变量可以安全地转换为const
限定类型。根据 C standard:
的第 6.3.2.3p2 节,这是允许的
For any qualifier q, a pointer to a non-q-qualified type may
be converted to a pointer to the q-qualified version of the
type; the values stored in the original and converted pointers shall
compare equal
这个
(int[3]) { 7, 8, 9 }
是 int[3]
类型的复合文字,用作函数参数,隐式转换为指向其第一个元素的指针。
另一方面(C 标准,6.3.2.3 指针)
1 A pointer to void may be converted to or from a pointer to any
object type. A pointer to any object type may be converted to a
pointer to void and back again; the result shall compare equal to the
original pointer.
和
2 For any qualifier q, a pointer to a non-q-qualified type may be
converted to a pointer to the q-qualified version of the type; the
values stored in the original and converted pointers shall compare
equal.
所以在这次通话中
memcpy(tab, (int[3]) { 7, 8, 9 }, sizeof(int) * 3);
复合字面量首先转换为 int *
类型的指针,指向其第一个元素,然后根据第一个引号转换为 void *
类型,然后转换为 const void *
根据第二个引用。
限定符const
表示指向的对象在函数内不会改变。并不意味着用作参数的表达式是常量表达式。
memcpy
的参数是memcpy(void *_Dst, const void *_Src, size_t _Size)
但是使用下面的代码,我传递了一个常量数组作为参数“_Src”,它仍然将数组的内容复制到目标中,即使我没有传递 const void *
。
int tab[3] = { 1, 2, 3 };
memcpy(tab, (int[3]) { 7, 8, 9 }, sizeof(int) * 3);
printf("%d %d %d \n", tab[0], tab[1], tab[2]); // Output: 7 8 9
表达式 (int[3]) { 7, 8, 9 }
returns 是指向数组第一个元素的指针吗?
当函数的参数声明为指向 const
类型的指针时,它“阻止”函数修改指针指向的内容(即不通过参数本身,但它可以通过强制转换), 但不限制实参类型为const
.
非const
限定类型的变量可以安全地转换为const
限定类型。根据 C standard:
For any qualifier q, a pointer to a non-q-qualified type may be converted to a pointer to the q-qualified version of the type; the values stored in the original and converted pointers shall compare equal
这个
(int[3]) { 7, 8, 9 }
是 int[3]
类型的复合文字,用作函数参数,隐式转换为指向其第一个元素的指针。
另一方面(C 标准,6.3.2.3 指针)
1 A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.
和
2 For any qualifier q, a pointer to a non-q-qualified type may be converted to a pointer to the q-qualified version of the type; the values stored in the original and converted pointers shall compare equal.
所以在这次通话中
memcpy(tab, (int[3]) { 7, 8, 9 }, sizeof(int) * 3);
复合字面量首先转换为 int *
类型的指针,指向其第一个元素,然后根据第一个引号转换为 void *
类型,然后转换为 const void *
根据第二个引用。
限定符const
表示指向的对象在函数内不会改变。并不意味着用作参数的表达式是常量表达式。