2013-08-20 42 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不是恕我直言。 –

相关问题