簡體   English   中英

錯誤:'f'的沖突類型和'f'的先前聲明在這里

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM