[英]error: conflicting types for '…'; note: previous implicit declaration of '…' was here
[英]error: conflicting types for 'f' and previous declaration of 'f' was here
這段代碼只是我在實際代碼中發現的一個非常大的情況,所以我給出了這個。 在此代碼中,結構“struct node”未定義,它在另一個c源文件中定義。
我的源代碼:
/* test.c */
1 #include<stdio.h>
2 #include "test2.h"
3
4 void f(struct node * k)
5 {
6
7 }
我的頭文件:
/* test2.h */
1 extern void f(struct node * k);
當我用gcc編譯這段代碼來創建一個目標文件時:
gcc -w -c test.c
我明白了:
test.c:6: error: conflicting types for 'f'
test2.h:1: error: previous declaration of 'f' was here
我已經給出了函數f()
的完整原型。 為什么我收到此錯誤?
另一件事是,當我不包括在test.c的頭文件test2.h和顯式聲明函數原型test.c
,它編譯成功。 代碼如下:
/* test.c */
1 #include<stdio.h>
2 void f(struct node *k);
3
4 void f(struct node * k)
5 {
6
7 }
gcc -c -w test.c
沒錯。
你能解釋為什么這次我沒有收到錯誤嗎?
這與原型上的extern
關鍵字無關(盡管沒有必要)。
您需要struct node
的前向聲明:
/* test2.h */
struct node; // <== this
extern void f(struct node * k);
如果沒有前向聲明,函數原型中的struct node
對於該特定函數原型是本地的 。
因此,當編譯器看到f()
的定義時,它還會看到struct node
另一個不同的本地聲明,並認為你對f()
有一個沖突的聲明。
見C99 6.9.1“標識符范圍”:
對於標識符指定的每個不同實體,標識符僅在稱為其范圍的程序文本的區域內可見(即,可以使用)。 由相同標識符指定的不同實體具有不同的范圍,或者在不同的名稱空間中。 范圍有四種:函數,文件,塊和函數原型。 (函數原型是聲明其參數類型的函數的聲明。)
...
如果聲明標識符的聲明符或類型說明符出現在函數原型(不是函數定義的一部分)的參數聲明列表中,則標識符具有函數原型作用域,該作用域終止於函數聲明符的末尾。
GCC 4.6.1為我提供了一個很好的警告:
C:\temp\test.c:3:22: warning: 'struct node' declared inside parameter list [enabled by default]
C:\temp\test.c:3:22: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
C ++使函數原型范圍僅適用於參數名稱(C ++ 03 3.3.3),因此如果將代碼編譯為C ++,則不會看到此問題。
從標題中刪除extern。 當您將函數聲明為外部函數時,您將指導編譯器不會編譯該函數,並且將在鏈接中解析對該函數的任何引用。 通常,此聲明在使用預編譯庫時完成。
在你的test2.h中你已經將f
聲明為extern
,這就是你得到錯誤的原因。 在test.c中,原型中沒有extern
聲明。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.