繁体   English   中英

C:为什么通过 arguments 小于 function 定义,只显示警告(没有任何错误,它可以正常运行)

[英]C : Why passing arguments less then function defined, Only warning shows up (No any error and it can run normally )

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

implicit declaration of function 'Wifi_Hosts_Sync_Func' [-Wimplicit-function-declaration]

我试图通过使用外部 function void *Wifi_Hosts_Sync_Func来消除它,但如果我这样做,编译器会显示错误:Wifi_Hosts_Sync_Func too little arguments。

我的问题是为什么这个代码可以工作? & WHY 程序没有崩溃或 flash 在“运行时”退出,定义 function 需要 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_dml.c

void *WiFi_HostSyncThread()
{
    fprintf(stderr,"[TRACE] before Wifi_Hosts_Sync_Func()");
    Wifi_Hosts_Sync_Func(NULL,0, NULL, 1);
    fprintf(stderr,"[TRACE] after  Wifi_Hosts_Sync_Func()");
}

在 cosa_wifi_apis.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 节:

如果在 function 调用中括号内的参数列表之前的表达式仅包含一个标识符,并且如果该标识符没有可见的声明,则该标识符被隐式声明,就好像在包含 function 调用的最里面的块中,声明extern int identifier(); 出现了。

这在 C99 中被删除了,因为它充其量是令人困惑的,最坏的情况是有害的。

Note that unlike C++, C uses () in the definition to say that the function takes an unknown number of arguments (none would be (void) ). 用任意数量的 arguments 调用它都可以,只需将所有这些 arguments 推入堆栈,这将取决于 function 来理解它们。

所以,它只是隐含地声明了一个外部 function 和未知数量的 arguments,所以它编译 - 虽然它仍然不正确。 And if it does work anyway then you just got lucky because the name still matched so the linker linked the real function and in the cdecl calling convention the caller clears up the stack, so the function would still run but see garbage (probably an unrelated local外部函数的变量)作为第 5 个参数。 由于它是一个 boolean 值,所发生的一切就是它被解释为真或假或随机的两者之一(但如果它是一个指针,它可能会造成各种破坏)。

如果你明确定义 function,你会得到一个错误,因为你(正确地)用 5 arguments 声明它,但你(错误地)用 4 调用它。

这就是为什么这个“特性”被删除的原因:它使代码看起来可以工作,实际上是被破坏的,这会导致后来出现奇怪的错误和混乱。

  1. 不带任何 arguments 的 Function 必须声明为TYPE func(void)而不是TYPE func() 永远不要声明这样的函数,因为它是一些历史上贬值的“特性”

  2. 在调用任何 function 之前,您需要拥有 function 原型,以让编译器知道 function 具有哪些返回类型和参数。

您的 function 还必须返回一个指针。

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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM