常量性和指针的指针 [英] constness and pointers to pointers
问题描述
我非常困惑的常量
关键字。我有一个函数接受字符串作为输入参数和函数接受可变数量的参数的数组。
I'm very much confused about the const
keyword. I have a function accepting an array of strings as input parameter and a function accepting a variable number of arguments.
void dtree_joinpaths(char* output_buffer, int count, ...);
void dtree_joinpaths_a(char* output_buffer, int count, const char** paths);
dtree_joinpaths
内部调用 dtree_joinpaths_a
之后,已建成从参数列表中的字符串数组。
dtree_joinpaths
internally invokes dtree_joinpaths_a
after it has built an array of strings from the argument list.
void dtree_joinpaths(char* output_buffer, int count, ...) {
int i;
va_list arg_list;
va_start(arg_list, count);
char** paths = malloc(sizeof(char*) * count);
for (i=0; i < count; i++) {
paths[i] = va_arg(arg_list, char*);
}
va_end(arg_list);
dtree_joinpaths_a(output_buffer, count, paths);
}
但 GCC
编译器给了我以下错误消息:
But the gcc
compiler gives me the following error message:
src/dtree_path.c: In function 'dtree_joinpaths':
src/dtree_path.c:65: warning: passing argument 3 of 'dtree_joinpaths_a' from incompatible pointer type
在更改的char **路径=的malloc(计数);
到为const char **路径=的malloc(计数);
,这个错误没有显示出来了。我不明白的是,那
When I change char** paths = malloc(count);
to const char** paths = malloc(count);
, this error is not showing up anymore. What I don't understand is, that
- 我想一个指针的地址总是可以铸造一个const指针,而不是倒过来(这是什么IMO这里发生)。
- 本例: HTTP://$c$cpad.org/mcPCMk3f
- I thought a pointer to an address can always be casted to a const pointer, but not the other way round (which is what is happening here imo).
- This example works: http://codepad.org/mcPCMk3f
我是什么做错了,或者是我的missunderstanding?
What am I doing wrong, or where is my missunderstanding?
我的意图是使输入数据的存储器不可变的功能。 (在这种情况下,路径
参数)。
My intent is to make the memory of the input data immutable for the function. (in this case the paths
parameter).
推荐答案
究其原因的char **
- > 为const char **
是一个危险的转换为以下code:
The reason char **
-> const char**
is a "dangerous" conversion is the following code:
const char immutable[] = "don't modify this";
void get_immutable_str(const char **p) {
*p = immutable;
return;
}
int main() {
char *ptr;
get_immutable_str(&ptr); // <--- here is the dangerous conversion
ptr[0] = 0;
}
以上code试图修改一个不可修改的对象,这是不确定的行为(为const char
的全局数组)。有这code的东西定义为坏没有其他候选人,所以const的安全规定,该指针转换是坏的。
The above code attempts to modify a non-modifiable object (the global array of const char
), which is undefined behavior. There is no other candidate in this code for something to define as "bad", so const-safety dictates that the pointer conversion is bad.
C不禁止的转换,但 GCC
警告你,这是不好的。仅供参考,C ++不禁止的转换,它有严格的const的安全性比C。
C does not forbid the conversion, but gcc
warns you that it's bad. FYI, C++ does forbid the conversion, it has stricter const-safety than C.
我会用一个字符串的例子,除了C,它字符串是危险的,开始用 - 你不能修改他们,但他们具有类型数组的 - 字符
,而不是数组的 - 为const char
。这是历史原因。
I would have used a string literal for the example, except that string literals in C are "dangerous" to begin with -- you're not allowed to modify them but they have type array-of-char
rather than array-of-const char
. This is for historical reasons.
我想一个指针的地址总是可以铸造一个const指针
I thought a pointer to an address can always be casted to a const pointer
一个指针到非const-T可以转换为一个指针给const-T。 的char **
- > 为const char **
不是模式的一个例子,因为如果 T
是的char *
然后常量牛逼
是字符* const的
,而不是为const char *
(在这一点上它可能是值得的不是写常量
左侧任何更多:写字符常量*
,你不会想到它是一样的 T常量
其中T是的char *
)。
A pointer-to-non-const-T can be converted to a pointer-to-const-T. char **
-> const char**
isn't an example of that pattern, because if T
is char *
then const T
is char * const
, not const char *
(at this point it's probably worthwhile not writing the const
on the left any more: write char const *
and you won't expect it to be the same as T const
where T is char *
).
您可以安全地转换的char **
到 char * const的*
,以及(对于需要一点点的原因不仅仅是简单的规则,更多),你可以安全地转换的char **
到字符常量* const的*
。
You can safely convert char **
to char * const *
, and (for reasons that require a little more than just the simple rule) you can safely convert char **
to char const * const *
.
这篇关于常量性和指针的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!