我的技能非常生疏,所以如果这是一个愚蠢的问题,我道歉,但我甚至不能想到要找到这个简单问题的答案。 此代码编译时没有任何警告:
#include <ruby.h>
int run_script( int argc, char *argv[] ) {
ruby_sysinit(&argc, &argv);
}
但是当我编译这段代码时,我收到以下警告:
#include <ruby.h>
int run_script( char * parameters ) {
int argc=0;
char *argv[1];
ruby_sysinit(&argc, &argv);
}
run_script_3.c: In function 'run_script':
run_script_3.c:7: warning: passing argument 2 of 'ruby_sysinit' from incompatible pointer type
似乎我在两种情况下都传递相同的指针类型。
答案 0 :(得分:2)
问题是形式参数声明中的数组等效于指针。宣言
int run_script( int argc, char *argv[] ) { ... }
相当于
int run_script( int argc, char **argv) { ... }
因为您无法将数组作为参数发送。您只能发送一个指针,即使您将数组作为实际参数,它也总是转换为指针。然后,如果你把&argv
放到了这个参数的地址,那么它就是系统堆栈中存储argv
值的地址。
另一方面,代码中的数组仍然是一个数组,它是不同的类型。在您的情况下,&argv
在char ***
的第一个版本中的类型为run_script
,而在第二个版本中的类型为char *(*)[1]
。它看起来像是同一类型,但事实并非如此。在运行时,存在更大的差异,因为您的两个调用正在向ruby_sysinit
发送两个完全不同的值。
你的第二个例子:
int run_script( char * parameters ) {
int argc=0;
char *argv[1];
ruby_sysinit(&argc, &argv);
}
可能会导致段错误,因为应用于数组的opearator &
会给出指向数组第一个元素的指针。因此,调用ruby_sysinit(&argc, &argv);
正在发送与ruby_sysinit(&argc, argv);
相同的值,即指向char*
的值,而不是指向char*
所指向的ruby_sysinit
。
答案 1 :(得分:0)
ruby_sysinit
的签名如下(如果我选择了错误的ruby版本,请更正我,我的系统上没有头文件):
void ruby_sysinit(int *argc, char ***argv);
这意味着以下编译:
extern void ruby_sysinit(int *argc, char ***argv);
int run_script(char * params) {
int argc = 0;
char **argv;
ruby_sysinit(&argc, &argv);
}
现在,当您声明char *argv[1]
时,您告诉编译器这是一个包含一个元素的数组。这与char **argv
不同。
编辑:您可能会发现this question on SO和this article (as linked in the other question)有用。