[英]why is this legal, c++ typedef func
我是在msvc 2005中做到的。
typedef void (*cleanup_t)();
void func(cleanup_t clean)
{
cleanup_t();
}
為什么編譯? 而不是給我一個警告? 好吧,它給了我一個未引用的形式參數警告但最初我做了這個當干凈在一個類沒有沒有未引用的形式參數時,這個代碼給我的問題。
什么是cleanup_t(); 真的在做什么,重點是什么? 現在笑了,我嘗試了int(),這也有效。
我認為這是一個表達式,其值為cleanup_t類型的默認值。 換句話說,一個表達式返回一個返回void的函數的NULL指針。
在C / C ++中,沒有副作用的表達式(這是 - 我認為)是有效的語句,就像你可以有一個語句一樣:
1 + 2;
這不是語法錯誤,但有些編譯器可能會發出警告。 它們通常不會對返回NULL值的無副作用表達式發出警告,或者只是變量名稱,因為這種類型的表達式通常在宏中用於調試目的(如assert()宏)。
您可以將其視為調用cleanup_t
類型的默認構造函數。 在C ++中添加了類似於內置類型(或其類型的typedef)的默認類似構造函數的語法,以便模板可以將作為模板參數傳入的類型的項設置為默認值,同時仍允許模板類型參數為非用戶定義的類型。 可能還有其他原因,但我相信這是其中之一。
就像是:
template <class T>
class foo
{
T myT;
public:
foo() {
myT = T();
};
};
typedef void (*cleanup_t)();
class bar
{
};
int not_quite_a_cleanup_t_func()
{
return 1;
}
int main()
{
foo<int> intFoo;
foo<cleanup_t> cleanup_t_foo;
foo<bar> barFoo;
// here I'm going to harp on one of the things I don't like about C++:
//
// That so many things that look like function calls are not or that
// the parens cause subtle behavior changes.
//
// I believe this is the reason this question was posted to
// stackoverflow, so it's not too far off topic.
//
// Many of these things exist because of backwards compatibility with C or
// because they wanted to fit in new features without adding keywords or
// new reserved tokens or making the parser even more complex than it already
// is. So there are probably good rationales for them.
//
// But I find it confusing more often than not, and the fact that there
// might be a rationale for it doesn't mean I have to like it...
cleanup_t cleanup1(); // declares a function named cleanup1 that returns a cleanup_t
cleanup_t cleanup2 = cleanup_t(); // cleanup2 is a variable of type cleanup_t that
// is default initialized
cleanup_t* cleanup3 = new cleanup_t; // cleanup3 is a pointer to type cleanup_t that
// is initialized to point to memory that is
// *not* initialized
cleanup_t* cleanup4 = new cleanup_t(); // cleanup4 is a pointer to type cleanup_t that
// is initialized to point to memory that *is*
// initialized (using default intialization)
cleanup2 = cleanup_t( not_quite_a_cleanup_t_func); // explicit type conversion using functional notation
cleanup_t(); // the OP's problem
cleanup2(); // call the function pointed to by cleanup2
(*cleanup2)(); // same thing
class cleanup_class
{
cleanup_t cleanup5;
public:
cleanup_class() :
cleanup5() // class member default initialization
{ };
};
}
它正在為cleanup_t類型執行一個默認初始化程序,以創建該類型的臨時文件,然后從不實際使用該臨時文件。
它很像構造函數調用,“MyClass c = MyClass();”的“MyClass()”部分,除了指針到函數類型實際上沒有構造函數。 當然在我的代碼片段中,“MyClass()”不一定會創建一個臨時的,因為它是一個初始化表達式。 “MyClass()。some_method();”中的“MyClass()” 也許是一個更接近的類比。
“int()”是另一種說“int(0)”的方式,這是另一種說“(int)0”的方式,這是另一種說“0”的方式。 同樣,它分配給一個臨時的,如果是整個語句,那么臨時是未使用的。
如果您在GCC上使用-Wall編譯問題中的代碼,則會收到警告“語句無效”。 執行此操作的人的代碼可能意味着鍵入“clean();”,不會產生該警告,因為它當然會產生調用該函數的效果。 切換警告的另一個原因,並正確地修復它們;-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.