Re: [問題] extern "C"的問題
看板C_and_CPP (C/C++)作者littleshan (我要加入劍道社!)時間16年前 (2009/06/10 14:59)推噓8(8推 0噓 5→)留言13則, 6人參與討論串4/5 (看更多)
※ 引述《QQ29 (我愛阿蓉)》之銘言:
: 標題: Re: [問題] extern "C"的問題
: 時間: Wed Jun 10 13:46:23 2009
:
: 不好意思 我現在自己想問題測試 其實我對extern "C"真的不是很懂
: z大說的我明白
: 而我現在寫法是這樣如下
:
: main.cpp
: #include <iostream>
: using namespace std;
: #include "test.h"
先挑一個和標題無關的錯誤:using namespace 不應該寫在任何 #include 之前
這算是滿糟糕的寫法,因為 compiler 不會報錯,
只有在發生名稱衝突時才吐一堆不知所云的訊息,而你不會想到是這行寫錯地方
: 以上這樣寫 是為了讓 test.c不去include test.h(我那個struct .c必須用到)
: 這樣可以compile過 但是我繼續想辦法try
: 我將extern "C"拿掉 test.c改成test.cpp
: 竟然就認不到了...........
你的「認不到」是指 compiler error 還是 link error?
錯誤訊息是什麼?
main.cpp:
#include "test.h"
int main()
{
foo();
return 0;
}
test.h:
#ifndef TEST_H
#define TEST_H
struct FU;
FU* foo();
#endif // TEST_H
test.cpp
typedef struct FF {
int x, y;
} FU;
FU* foo()
{
return NULL;
}
以上的 code 可以順利 compile、link 並執行
但其中卻隱含了非常邪惡的地方
那就是在 test.h 中並沒有 typedef 的敘述
所以你在 test.cpp 中雖然使用了 typedef
但含入 test.h 的 main.cpp 中並不知道「FF」這個 struct 的存在
它得到的資訊僅是:
foo() 是一個函式,不接受參數,傳回一個指向 FU 的指標
而 test.cpp 呢?因為 typedef 的緣故,它知道 FU 只是 FF 的別名,
所以你定義的 foo() 是:
foo() 是一個函式,不接受參數,傳回一個指向 FF 的指標
所以你的定義和宣告已經如同政客般言行不一了
但運氣很好 (從另一個角度來看,應該說不好才對) 的是
C++ 的函式回傳型別並不會成為 name mangling 的一部份
所以上述的 foo() 雖然本質上是不同的
但它們在編譯時會變成相同的 symbol
因此上述的程式可以順利連結
如果你改成以下的寫法,就過不了關了:
test.h:
#ifndef TEST_H
#define TEST_H
struct FU;
void foo(FU*);
#endif // TEST_H
test.cpp
typedef struct FF {
int x, y;
} FU;
void foo(FU*)
{
return;
}
: 原因很想請板上高手解釋一下
:
: 因為我知道struct改成class的話 上面的改法 就不會有問題
C++ 中 struct 和 class 幾乎完全相同,
唯一的不同在於 struct 預設成員為 public
而 class 預設成員為 private
其它使用方法完全相同
: 1.為什麼struct卻不能呢?
因為你用了 typedef
: 2.一開始我這樣故意把.c的include .h拿掉是不是一個好的作法?
不是
因為你的 .c 明顯是要實作 .h 提供的介面
不去 include 是自找麻煩
: 不然勢必extern "C"就要寫在main ==>extern "C"{include "test.h"}
一般會這樣寫:
#ifndef TEST_H
#define TEST_H
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
typedef struct FF {
int x, y;
} FF;
FF* foo(void);
#ifdef __cplusplus
} // end of extern "C"
#endif // __cplusplus
#endif // TEST_H
這樣你的 test.h 就能讓 C/C++ compiler 同時使用
: → QQ29:你好~typedef我認知是 定義struct並且給一個(以上)別名之類的 06/10 14:04
: → QQ29:我是不清楚 看很多他人寫的程式都很愛使用typedef struct 06/10 14:05
: → QQ29:但是實際上的好處以及在我問的問題上 差異在哪裡!! 06/10 14:05
C 裡面的 struct 名稱不能直接當型別使用,需要在前面多加 struct 關鍵字:
struct Point {
int x, y;
};
void foo()
{
Point p; // error
struct Point p; // OK
}
所以很多人會這樣寫:
typedef struct Point {
int x, y;
} Point;
void foo()
{
Point p; // OK
}
但是 C++ 已經沒有這層限制了:
struct Point {
int x, y;
};
class Line {
Point start, end;
};
void foo()
{
Point p; // OK
Line l; // OK
}
大大您也是 C_and_CPP 的常客了,也該積極了解自己寫出每行 code 的真正意義。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 219.87.151.2
推
06/10 15:02, , 1F
06/10 15:02, 1F
→
06/10 15:02, , 2F
06/10 15:02, 2F
推
06/10 15:09, , 3F
06/10 15:09, 3F
推
06/10 15:22, , 4F
06/10 15:22, 4F
→
06/10 15:22, , 5F
06/10 15:22, 5F
推
06/10 15:37, , 6F
06/10 15:37, 6F
推
06/10 15:38, , 7F
06/10 15:38, 7F
推
06/10 15:40, , 8F
06/10 15:40, 8F
推
06/10 15:56, , 9F
06/10 15:56, 9F
→
06/10 15:57, , 10F
06/10 15:57, 10F
→
06/10 15:57, , 11F
06/10 15:57, 11F
推
06/10 16:19, , 12F
06/10 16:19, 12F
→
06/10 16:19, , 13F
06/10 16:19, 13F
討論串 (同標題文章)
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章