Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C:为什么传递的参数少于函数定义的参数,只显示警告(没有任何错误,它可以正常运行)_C_Arguments_Compiler Warnings - Fatal编程技术网

C:为什么传递的参数少于函数定义的参数,只显示警告(没有任何错误,它可以正常运行)

C:为什么传递的参数少于函数定义的参数,只显示警告(没有任何错误,它可以正常运行),c,arguments,compiler-warnings,C,Arguments,Compiler Warnings,这可能是个特例。当我跟踪C代码时,我看到了警告。说 函数“Wifi\u Hosts\u Sync\u Func”的隐式声明[-Wimplicit函数声明] 我试图通过使用函数void*Wifi\u Hosts\u Sync\u Func来消除它 但如果我这样做,编译器会显示错误:Wifi\u Hosts\u Sync\u Func参数太少 我的问题是为什么这个代码可以工作为什么程序在运行时没有崩溃或闪烁。 定义的函数需要5个参数,调用代码只需要4个参数。 该程序可以正常运行并成功结束。有什么想法

这可能是个特例。当我跟踪C代码时,我看到了警告。说

函数“Wifi\u Hosts\u Sync\u Func”的隐式声明[-Wimplicit函数声明]

我试图通过使用函数void*Wifi\u Hosts\u Sync\u Func来消除它 但如果我这样做,编译器会显示错误:Wifi\u Hosts\u Sync\u Func参数太少

我的问题是为什么这个代码可以工作为什么程序在运行时没有崩溃或闪烁。 定义的函数需要5个参数,调用代码只需要4个参数。 该程序可以正常运行并成功结束。有什么想法吗

// warning msg. ../../../../git/source/TR-181/ml/cosa_wifi_dml.c: In function 'WiFi_HostSyncThread': ../../../../git/source/TR-181/ml/cosa_wifi_dml.c:756:2: warning: implicit declaration of function 'Wifi_Hosts_Sync_Func' [-Wimplicit-function-declaration] Wifi_Hosts_Sync_Func(NULL,0, NULL, 1); ^~~~~~~~~~~~~~~~~~~~ 在cosa_wifi_api.c中

void *Wifi_Hosts_Sync_Func(void *pt, int index, wifi_associated_dev_t *associated_dev, BOOL bCallForFullSync, BOOL bCallFromDisConnCB )
{
    fprintf(stderr,"[TRACE] Wifi_Hosts_Sync_Func() Call in.\n");
   ...
   ...
}

根据C89第3.3.2.2节:

如果函数调用中括号参数列表前面的表达式仅由标识符组成,并且如果该标识符没有可见的声明,则该标识符被隐式声明,就像在包含函数调用的最内层块中声明extern int标识符一样;出现了

但在C99中删除了它,因为它最好是令人困惑的,最坏是有害的

注意,与C++不同,C使用定义来定义函数的数量未知,没有一个是无效的。使用任意数量的参数调用它都会起作用,只需将所有这些参数推送到堆栈中,函数就可以理解它们

因此,它只是隐式声明了一个具有未知参数数的外部函数,所以它进行编译——尽管它仍然不正确。如果它确实能工作,那么你就幸运了,因为名称仍然匹配,所以链接器链接了真正的函数,在cdecl调用约定中,调用者清除了堆栈,所以函数仍然会运行,但是垃圾可能是外部函数的一个不相关的局部变量,作为第五个参数。由于它是一个布尔值,所有发生的事情就是它被解释为真或假,或者随机地解释为两个值中的一个,但是如果它是,比如说,一个指针,它可能会造成各种破坏

如果显式定义函数,则会出现错误,因为您用5个参数正确地声明了函数,但用4个参数错误地调用了函数


这就是删除此功能的原因:它使代码看起来正常工作,但实际上已损坏,这会导致奇怪的错误和以后的混淆。

来自C89,第3.3.2.2节:

如果函数调用中括号参数列表前面的表达式仅由标识符组成,并且如果该标识符没有可见的声明,则该标识符被隐式声明,就像在包含函数调用的最内层块中声明extern int标识符一样;出现了

但在C99中删除了它,因为它最好是令人困惑的,最坏是有害的

注意,与C++不同,C使用定义来定义函数的数量未知,没有一个是无效的。使用任意数量的参数调用它都会起作用,只需将所有这些参数推送到堆栈中,函数就可以理解它们

因此,它只是隐式声明了一个具有未知参数数的外部函数,所以它进行编译——尽管它仍然不正确。如果它确实能工作,那么你就幸运了,因为名称仍然匹配,所以链接器链接了真正的函数,在cdecl调用约定中,调用者清除了堆栈,所以函数仍然会运行,但是垃圾可能是外部函数的一个不相关的局部变量,作为第五个参数。由于它是一个布尔值,所有发生的事情就是它被解释为真或假,或者随机地解释为两个值中的一个,但是如果它是,比如说,一个指针,它可能会造成各种破坏

如果显式定义函数,则会出现错误,因为您用5个参数正确地声明了函数,但用4个参数错误地调用了函数

这就是为什么删除了这个特性:它使代码看起来像是在工作,但实际上是坏的,这会导致奇怪的错误和以后的混乱

不接受任何参数的函数必须声明为 类型funcvoid不是类型func。永远不要声明这样的函数,因为它是一些历史折旧的特性

在调用任何函数之前,您需要有函数原型,让编译器知道函数的返回类型和参数

函数还必须返回指针

void *Wifi_Hosts_Sync_Func(void *pt, int index, wifi_associated_dev_t *associated_dev, BOOL bCallForFullSync, BOOL bCallFromDisConnCB );

void *WiFi_HostSyncThread(void)
{
    void *result;
    fprintf(stderr,"[TRACE] before Wifi_Hosts_Sync_Func()");
    result = Wifi_Hosts_Sync_Func(NULL,0, NULL, 1);   // and now you will have the error here.
    fprintf(stderr,"[TRACE] after  Wifi_Hosts_Sync_Func()");
    return result;
}
不接受任何参数的函数必须声明为 类型funcvoid不是类型func。永远不要声明这样的函数,因为它是一些历史折旧的特性

在调用任何函数之前,您需要有函数原型,让编译器知道函数的返回类型和参数

函数还必须返回指针

void *Wifi_Hosts_Sync_Func(void *pt, int index, wifi_associated_dev_t *associated_dev, BOOL bCallForFullSync, BOOL bCallFromDisConnCB );

void *WiFi_HostSyncThread(void)
{
    void *result;
    fprintf(stderr,"[TRACE] before Wifi_Hosts_Sync_Func()");
    result = Wifi_Hosts_Sync_Func(NULL,0, NULL, 1);   // and now you will have the error here.
    fprintf(stderr,"[TRACE] after  Wifi_Hosts_Sync_Func()");
    return result;
}

您似乎没有包含声明函数的相关头,就这么简单。至于为什么它似乎无论如何都能起作用——可能是
是一些C90隐式整数的失败。代码不起作用。正如您所提到的,它应该在运行时崩溃,但不会。不做应该做的事情是不起作用的。@DavidSchwartz在C语言中没有崩溃这样的事情。在C++标准中,它甚至没有提到过一次。没有C程序应该崩溃。在任何地方都没有这样的义务。经验法则:总是把函数的警告隐式声明看作一个错误。在函数被声明的情况下,似乎没有包含相关的标头,这是简单的。至于为什么它似乎无论如何都能工作——可能是一些C90隐式int的失败。代码不起作用。正如您所提到的,它应该在运行时崩溃,但不会。不做应该做的事情是不起作用的。@DavidSchwartz在C语言中没有崩溃这样的事情。在C++标准中,它甚至没有提到过一次。没有C程序应该崩溃。在任何地方都没有这样的义务。经验法则:总是把函数的警告隐式声明看作是一个错误。