[英]Multiple implicit declaration of same function in C
這是我的代碼:
int main(){
printf("Hi");
int i=10;
printf("Hi %d",i);
return 0;
}
現在,由於C可以隱式聲明一個函數,因此該程序將正確編譯(與gcc一樣)。
但是我的問題是,不是第一個printf
聲明返回具有char *
類型的1參數的char *
嗎?
這會使第二個printf
出錯。
但是該程序編譯時沒有錯誤,只是警告(gcc)。 為什么呢
嚴格來說,隱式聲明是標准違規行為。 它已從標准中刪除。
引用C11
,前言
第二版的主要變化包括:
—刪除隱式函數聲明
這就是說,在C的早期版本中,這被認為是隱式聲明的函數(即編譯器之前采用了對函數的原型知識) 本來是要
int
因此,只要函數聲明和定義不沖突(例如,返回類型不匹配),就不會出現任何錯誤。 但是,嚴格符合要求的編譯器必須產生診斷信息。
在您的情況下, printf
被隱式定義為int printf(...)
,而不是int printf(char *)
,因此,當您使用其他參數調用編譯器時,編譯器不會檢測到錯誤。
您的代碼不是可移植的C,因為您缺少必不可少的#include
,后者為printf
了函數原型:C99中刪除了任何類型的隱式聲明。
如果要編寫不可移植的C,那么最好的辦法是查閱編譯器文檔。 在這種情況下,您友好的編譯器似乎默認為int printf(...)
。
不幸的是,即使沒有使用頭文件,gcc也有一些內置的printf概念。
unsigned int fun ( unsigned int x )
{
printf("%s\n");
printf("%u\n",x);
more_fun("%s\n");
more_fun("%u\n",x);
return(x+1);
}
so.c: In function ‘fun’:
so.c:5:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
printf("%s\n");
^
so.c:5:5: warning: incompatible implicit declaration of built-in function ‘printf’
so.c:5:5: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’
so.c:5:12: warning: format ‘%s’ expects a matching ‘char *’ argument [-Wformat=]
printf("%s\n");
^
so.c:7:5: warning: implicit declaration of function ‘more_fun’ [-Wimplicit-function-declaration]
more_fun("%s\n");
^
幸運的是,如果我們自己制造,它至少會遺忘一點。
void printf(char *, unsigned int );
void more_fun(char *, unsigned int );
unsigned int fun ( unsigned int x )
{
printf("%s\n");
printf("%u\n",x);
more_fun("%s\n");
more_fun("%u\n",x);
return(x+1);
}
so.c:3:6: warning: conflicting types for built-in function ‘printf’
void printf(char *, unsigned int );
^
so.c: In function ‘fun’:
so.c:7:5: error: too few arguments to function ‘printf’
printf("%s\n");
^
so.c:3:6: note: declared here
void printf(char *, unsigned int );
^
so.c:9:5: error: too few arguments to function ‘more_fun’
more_fun("%s\n");
^
so.c:4:6: note: declared here
void more_fun(char *, unsigned int );
^
但是我們談論的是一個編譯器,一個編譯器不能解決這個問題,您必須嘗試很多/全部。 無論標准編譯器與否,編譯器仍會注意到您對該函數的使用進行了更改,並讓您知道,該編譯器選擇不這樣做。 這里的錯誤不是因為編譯器沒有注意到該函數在一個未聲明的實例和另一個未聲明的實例之間的用法不同,而是沒有聲明,然后它確實注意到了所希望的差異。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.