带点的预处理器宏

Preprocessor macro with dot?

本文关键字:处理器 预处理      更新时间:2023-10-16

是否可以定义一个宏来接受像:object.method()这样的表达式?我想创建一个宏,将该表达式更改为…什么也没有(删除了它)。只有function()我会做:#define function(没有任何值),但是否有可能创建一个宏点在它?

编辑:关于MooingDuck的评论:

object.Method("text", "other");

定义:

void Class::Method(std::string arg1, std::string arg2)
{
#if 0
    if (condition)
    {
        Method2(arg1, arg2);
    }
#endif
}

拆卸:

    object.Method("text", "other");
00394396  mov         edi,5  
0039439B  mov         eax,offset string "other" (396348h)  
003943A0  lea         esi,[ebp-4Ch]  
003943A3  mov         dword ptr [ebp-38h],0Fh  
003943AA  mov         dword ptr [ebp-3Ch],ebx  
003943AD  mov         byte ptr [ebp-4Ch],bl  
003943B0  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign (393360h)  
003943B5  mov         dword ptr [ebp-4],1  
003943BC  mov         edi,4  
003943C1  mov         eax,offset string "text" (396350h)  
003943C6  lea         esi,[ebp-30h]  
003943C9  mov         dword ptr [ebp-1Ch],0Fh  
003943D0  mov         dword ptr [ebp-20h],ebx  
003943D3  mov         byte ptr [ebp-30h],bl  
003943D6  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign (393360h)  
003943DB  mov         esi,10h  
003943E0  mov         dword ptr [ebp-4],0FFFFFFFFh  
003943E7  cmp         dword ptr [ebp-1Ch],esi  
003943EA  jb          main+0B9h (3943F9h)  
003943EC  mov         eax,dword ptr [ebp-30h]  
003943EF  push        eax  
003943F0  call        dword ptr [__imp_operator delete (3960ECh)]  
003943F6  add         esp,4  
003943F9  mov         edi,0Fh  
003943FE  mov         dword ptr [ebp-1Ch],edi  
00394401  mov         dword ptr [ebp-20h],ebx  
00394404  mov         byte ptr [ebp-30h],bl  
00394407  cmp         dword ptr [ebp-38h],esi  
0039440A  jb          main+0D9h (394419h)  
0039440C  mov         ecx,dword ptr [ebp-4Ch]  
0039440F  push        ecx  
00394410  call        dword ptr [__imp_operator delete (3960ECh)]  
00394416  add         esp,4  

你的代码是:

void Class::Method(const std::string& arg1, const std::string& arg2)
{
#if 0
    if (condition)
    {
        Method2(arg1, arg2);
    }
#endif
}

但是问题是,当你用字符串字面值调用它时,它仍然在构造std::string对象,因为构造它们的过程可能有副作用。

我想我会尝试这个,它不会做转换,直到函数内部,因此编译器也可以省略std::string结构。

template<class arg1_t, class arg2_t>
void Class::Method(const arg1_t& arg1, const arg2_t& arg2)
{
#if 0
    if (condition)
    {
        Method2(arg1, arg2);
    }
#endif
}

宏的名称是一个标识符。没有别的办法。

不同的编译器可能允许不同的字符作为标识符(如$),但它们都不允许.。最后,c预处理器被设计成一个"轻型预处理器",而不是像80年代中期存在的其他更强大的预处理器那样用于花哨的转换。

尽管你可以这样做(不太推荐):

struct DoNothing
{
    void method() { }
};
DoNothing g_inst;
#define object g_inst

几乎可以肯定,宏生成的代码将被优化器完全删除。这种方法对所有已使用的名称都很敏感。