2013-08-20 45 views
2

當函數沒有任何參數,它可以通過define作爲調用C中沒有括號的參數的函數?

#define test test() 

是否可調用參數的函數,而不paranthesis調用它沒有括號?類似於

#define test test(char *arg) 

test "argument 1"; 
+8

你爲什麼要這樣做? – luiscubal

+0

@luiscubal主要是出於好奇(不是必需品)。我想知道'C'有多大的靈活性來改變它在高級語言中的編碼。 – Googlebot

+2

函數優先級的規則是:foo x + bar y foo(x)+ bar(y)'或'foo(x + bar(y))'?無論哪種方式,我99%肯定無法在普通的C中做到這一點。 – luiscubal

回答

13

這不可能以C的方式實現。標準(C99)的第6.5.2節描述了後綴表達式,並且沒有像這樣的語法。函數調用(§6.5.2.2):

後綴表達式後跟包含表達式的可能是空的,逗號分隔的列表括號()是一個函數調用。後綴表達式表示被調用函數。表達式列表指定函數的參數。

Parens不是可選的,它們需要包裝所有的參數,所以你需要一個類似於函數的宏(它需要parens在「call」站點)或者兩個獨立的東西(一個插入啓動頁面,一個插入關閉的一個)。

你可以這樣做:

#define test puts(
#define end ); 
#define int_proc int 
#define proc_body { 
#define proc_end } 
#define no_args (void) 
#include <stdio.h> 

int_proc main no_args 
proc_body 
    test "hello" end 
proc_end 

但是......真的嗎?

C++提供了更多的可能性,特別是運算符重載。如果你想「定製」一些語法,你可能需要研究一下。

這是一個可怕的例子:

#include <iostream> 

struct Foo { 
    void operator=(char const* str) 
    { 
     std::cout << str << std::endl; 
    } 
}; 
Foo global_foo; 

#define test global_foo = 

int main() 
{ 
    test "hello"; 
} 

注意這裏,你可能會覺得有吸引力理智的方法,例如Qt的qDebug實用程序類。示意性地,它是這樣的:

#include <iostream> 

struct debug { 
    debug() {} 
    ~debug() 
    { 
     std::cout << std::endl; 
    } 
    debug const& operator<<(char const* msg) const 
    { 
     std::cout << msg << " "; 
     return *this; 
    } 
}; 

使用這將是通常使用的方法:

debug() << "this" << "works"; 

如果添加一個構造函數char const*

debug(char const*msg) 
{ 
    std::cout << msg << " "; 
} 

然後你可以使用演員表演和寫作:

(debug) "Hello"; 

這是非常接近你的(和宏觀)。

然後你可以看到所有其他運營商(operator,將是一個主要候選人),但優先規則可能會毀了有趣的一點。

+1

+1:在旁觀者眼中可怕。請參閱[googletest](https://code.google.com/p/googletest/wiki/Primer):'ASSERT_EQ(expected,actual)<<「message to show if failure」;' – rwong

+0

@rwong:聲明至少類似於有效的C++語句。 '測試「你好」;'沒有,任何使它合法的東西都是這個原因可怕的。什麼googletest不是恕我直言。 –

相關問題