2011-08-21 60 views
0

按照另一個question I had asked earlier我想我可能已經找到了我的問題,但我需要專家的眼球。是否可以重複導致編譯錯誤的C源代碼?

我發現文件/net/ipv4/tcp_zero_copy.c這導致了我的內核編譯失敗。

當我在C/C++編輯器中查看文件時,我對C或C++沒有多少了解,它看起來像相同的代碼重複了一遍(我認爲是4次)。

我的問題很簡單;

這足以導致編譯器出現問題嗎?如果相同的代碼在同一個文件中反覆出現?

這是該文件的源代碼(總共148行,從頭到尾);

/* 
* Support routines for TCP zero copy transmit 
* 
* Created by Vladislav Bolkhovitin 
* 
* This program is free software; you can redistribute it and/or 
*  modify it under the terms of the GNU General Public License 
*  version 2 as published by the Free Software Foundation. 
*/ 

#include <linux/skbuff.h> 

net_get_page_callback_t net_get_page_callback __read_mostly; 
EXPORT_SYMBOL(net_get_page_callback); 

net_put_page_callback_t net_put_page_callback __read_mostly; 
EXPORT_SYMBOL(net_put_page_callback); 

/* 
* Caller of this function must ensure that at the moment when it's called 
* there are no pages in the system with net_priv field set to non-zero 
* value. Hence, this function, as well as net_get_page() and net_put_page(), 
* don't need any protection. 
*/ 
int net_set_get_put_page_callbacks(
    net_get_page_callback_t get_callback, 
    net_put_page_callback_t put_callback) 
{ 
    int res = 0; 

    if ((net_get_page_callback != NULL) && (get_callback != NULL) && 
     (net_get_page_callback != get_callback)) { 
     res = -EBUSY; 
     goto out; 
    } 

    if ((net_put_page_callback != NULL) && (put_callback != NULL) && 
     (net_put_page_callback != put_callback)) { 
     res = -EBUSY; 
     goto out; 
    } 

    net_get_page_callback = get_callback; 
    net_put_page_callback = put_callback; 

out: 
    return res; 
} 
EXPORT_SYMBOL(net_set_get_put_page_callbacks); 
/* 
* Support routines for TCP zero copy transmit 
* 
* Created by Vladislav Bolkhovitin 
* 
* This program is free software; you can redistribute it and/or 
*  modify it under the terms of the GNU General Public License 
*  version 2 as published by the Free Software Foundation. 
*/ 

#include <linux/skbuff.h> 

net_get_page_callback_t net_get_page_callback __read_mostly; 
EXPORT_SYMBOL(net_get_page_callback); 

net_put_page_callback_t net_put_page_callback __read_mostly; 
EXPORT_SYMBOL(net_put_page_callback); 

/* 
* Caller of this function must ensure that at the moment when it's called 
* there are no pages in the system with net_priv field set to non-zero 
* value. Hence, this function, as well as net_get_page() and net_put_page(), 
* don't need any protection. 
*/ 
int net_set_get_put_page_callbacks(
    net_get_page_callback_t get_callback, 
    net_put_page_callback_t put_callback) 
{ 
    int res = 0; 

    if ((net_get_page_callback != NULL) && (get_callback != NULL) && 
     (net_get_page_callback != get_callback)) { 
     res = -EBUSY; 
     goto out; 
    } 

    if ((net_put_page_callback != NULL) && (put_callback != NULL) && 
     (net_put_page_callback != put_callback)) { 
     res = -EBUSY; 
     goto out; 
    } 

    net_get_page_callback = get_callback; 
    net_put_page_callback = put_callback; 

out: 
    return res; 
} 
EXPORT_SYMBOL(net_set_get_put_page_callbacks); 
/* 
* Support routines for TCP zero copy transmit 
* 
* Created by Vladislav Bolkhovitin 
* 
* This program is free software; you can redistribute it and/or 
*  modify it under the terms of the GNU General Public License 
*  version 2 as published by the Free Software Foundation. 
*/ 

#include <linux/skbuff.h> 

net_get_page_callback_t net_get_page_callback __read_mostly; 
EXPORT_SYMBOL(net_get_page_callback); 

net_put_page_callback_t net_put_page_callback __read_mostly; 
EXPORT_SYMBOL(net_put_page_callback); 

/* 
* Caller of this function must ensure that at the moment when it's called 
* there are no pages in the system with net_priv field set to non-zero 
* value. Hence, this function, as well as net_get_page() and net_put_page(), 
* don't need any protection. 
*/ 
int net_set_get_put_page_callbacks(
    net_get_page_callback_t get_callback, 
    net_put_page_callback_t put_callback) 
{ 
    int res = 0; 

    if ((net_get_page_callback != NULL) && (get_callback != NULL) && 
     (net_get_page_callback != get_callback)) { 
     res = -EBUSY; 
     goto out; 
    } 

    if ((net_put_page_callback != NULL) && (put_callback != NULL) && 
     (net_put_page_callback != put_callback)) { 
     res = -EBUSY; 
     goto out; 
    } 

    net_get_page_callback = get_callback; 
    net_put_page_callback = put_callback; 

out: 
    return res; 
} 
EXPORT_SYMBOL(net_set_get_put_page_callbacks); 

**編輯**

而且我只是用記事本++到它看起來像他們結束的代碼的各個塊進行比較。根據比較工具全部3塊互相匹配。

這是從它死亡的地方到它返回給我的命令提示符的編譯器輸出。

CC  net/ipv4/tcp_zero_copy.o 
net/ipv4/tcp_zero_copy.c:63:1: error: redefinition of â__kcrctab_net_get_page_callbackâ 
net/ipv4/tcp_zero_copy.c:14:1: note: previous definition of â__kcrctab_net_get_page_callbackâ was here 
net/ipv4/tcp_zero_copy.c:63:1: error: redefinition of â__kstrtab_net_get_page_callbackâ 
net/ipv4/tcp_zero_copy.c:14:1: note: previous definition of â__kstrtab_net_get_page_callbackâ was here 
net/ipv4/tcp_zero_copy.c:63:1: error: redefinition of â__ksymtab_net_get_page_callbackâ 
net/ipv4/tcp_zero_copy.c:14:1: note: previous definition of â__ksymtab_net_get_page_callbackâ was here 
net/ipv4/tcp_zero_copy.c:66:1: error: redefinition of â__kcrctab_net_put_page_callbackâ 
net/ipv4/tcp_zero_copy.c:17:1: note: previous definition of â__kcrctab_net_put_page_callbackâ was here 
net/ipv4/tcp_zero_copy.c:66:1: error: redefinition of â__kstrtab_net_put_page_callbackâ 
net/ipv4/tcp_zero_copy.c:17:1: note: previous definition of â__kstrtab_net_put_page_callbackâ was here 
net/ipv4/tcp_zero_copy.c:66:1: error: redefinition of â__ksymtab_net_put_page_callbackâ 
net/ipv4/tcp_zero_copy.c:17:1: note: previous definition of â__ksymtab_net_put_page_callbackâ was here 
net/ipv4/tcp_zero_copy.c:74:5: error: redefinition of ânet_set_get_put_page_callbacksâ 
net/ipv4/tcp_zero_copy.c:25:5: note: previous definition of ânet_set_get_put_page_callbacksâ was here 
net/ipv4/tcp_zero_copy.c:98:1: error: redefinition of â__kcrctab_net_set_get_put_page_callbacksâ 
net/ipv4/tcp_zero_copy.c:49:1: note: previous definition of â__kcrctab_net_set_get_put_page_callbacksâ was here 
net/ipv4/tcp_zero_copy.c:98:1: error: redefinition of â__kstrtab_net_set_get_put_page_callbacksâ 
net/ipv4/tcp_zero_copy.c:49:1: note: previous definition of â__kstrtab_net_set_get_put_page_callbacksâ was here 
net/ipv4/tcp_zero_copy.c:98:1: error: redefinition of â__ksymtab_net_set_get_put_page_callbacksâ 
net/ipv4/tcp_zero_copy.c:49:1: note: previous definition of â__ksymtab_net_set_get_put_page_callbacksâ was here 
make[2]: *** [net/ipv4/tcp_zero_copy.o] Error 1 
make[1]: *** [net/ipv4] Error 2 
make: *** [net] Error 2 
[email protected]:/usr/src/linux# ls 
+0

直接的答案是肯定的,這是一個問題。更有趣的答案將是這個問題發生的原因或方式。 –

+0

@Solignis:這是哪個版本的內核? (完整版,包括平臺,操作系統等) –

回答

1

這取決於被重複什麼,

函數聲明重複不會給任何錯誤。
重複的函數定義會給出錯誤。
正在創建\定義爲相同名稱的變量會給出錯誤。

#2 & #3給出錯誤,因爲他們打破了ODR(一個定義規則)。

void doSomething(); //no error 
void doSomething(); 
void doSomething(); 

void doSomething() 
{ 

} 

int main() 
{ 
    int i; //error 
    int i; 
    doSomething(); 
    return 1; 
} 

在此代碼:

net_get_page_callback_t net_get_page_callback __read_mostly; 

限定可變的,並且這樣做多次,導致相同的命名變量的多個定義,因而重定義錯誤。

+0

所以它們是多餘的?所以刪除它們並保持代碼塊#1?一切都應該好? – ianc1215

+0

@Solignis:是的,他們是簡化版,也許有人在代碼中不小心複製了粘貼的代碼塊? –

+0

是啊不知道如何可以通過。無論如何希望它會在這次工作。 – ianc1215

1

函數在翻譯單元中被多次定義是錯誤的。這是發生在這裏的事情。嘗試發佈編譯中的前幾個錯誤消息。

+0

我從它死亡的地方添加了輸出。 – ianc1215

+0

是的,錯誤消息證實了這一點。 –