C-使#定义#x27;返回';价值

C-使#定义#x27;返回';价值,c,C,假设我有这样的定义: #define CrWinDef(a,b,c,d,e,f,g,h,i,j,k,l)\ {\ HWND thw=CreateWindowEx(a,b,c,d,e,f,g,h,i,j,k,l);\ SendMessage(thw, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)true);\ } 现在在我的代码中,我想使用变量“thw”。 仅使用 CrWinDef(...); 工作

假设我有这样的定义:

#define CrWinDef(a,b,c,d,e,f,g,h,i,j,k,l)\
{\
    HWND thw=CreateWindowEx(a,b,c,d,e,f,g,h,i,j,k,l);\
    SendMessage(thw, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)true);\
}
现在在我的代码中,我想使用变量“thw”。 仅使用

CrWinDef(...);
工作

但是,如果添加返回thw;我定义并尝试在它不会编译的代码中使用相同的值

#define CrWinDef(a,b,c,d,e,f,g,h,i,j,k,l)\
    {\
        HWND thw=CreateWindowEx(a,b,c,d,e,f,g,h,i,j,k,l);\
        SendMessage(thw, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)true);\
return thw;\
    }
和代码

 HWND hwnd = CrWinDef(...);
您的CrWinDef“函数”没有定义返回类型

为什么不使用函数?

#define
盲目复制并粘贴定义,无论您在何处引用它

HWND hwnd = CrWinDef(...);
在编译的预处理步骤中,宏将扩展到此

HWND hwnd = 
{
    HWND thw = CreateWindowEx(...);

    SendMessage(thw, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)true);

    return thw;
}
这并不完全有意义,因为您将“分配新范围的值”给
HWND

您可以修改宏以在当前范围中定义
HWND
实例,而不是从获取返回值的函数的角度来查看它

#define CrWinDef(name, a,b,c,d,e,f,g,h,i,j,k,l)\
    HWND name = CreateWindowEx(a,b,c,d,e,f,g,h,i,j,k,l);\
    SendMessage(name, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)true);\

// "hwnd" now contains the HWND instance
CrWinDef(hwnd, ...);

最后一个选项是创建一个实际函数,该函数执行宏中的操作,但需要在参数中包含相应的类型信息。

正如其他答案所指出的,宏不能有返回值

但在大多数情况下,
静态内联
函数将产生相同的结果(函数将内联),但增加了类型安全性,这是宏无法实现的。

如果使用(或类似的兼容编译器)编译,则可以使用其语言扩展和代码:

#define CrWinDef(a,b,c,d,e,f,g,h,i,j,k,l) ({\
 HWND thw=CreateWindowEx(a,b,c,d,e,f,g,h,i,j,k,l);\
 SendMessage(thw, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), \
            (LPARAM)true);\
 thw; })
然后稍后使用:
HWND-HWND=CrWinDef(
但这不适用于例如Microsoft编译器

正如其他人所建议的那样,
静态内联
函数将更干净、更可移植。宏是脆弱的,例如,如果它们的参数是
i++
,因为它可能被替换多次,例如

#define SQUARE(X) ((X)*(X))

SQUARE(i++)
一起使用-这是并且可能会增加
i
两次。

我不认为你所要求的在C中是可能的,但是你可以通过滥用来实现它下面的代码不是任何人都应该实际使用的,它代表了我为满足OP最初的请求而做出的超越理性界限的顽强尝试

#define CrWinDef(var,a,b,c,d,e,f,g,h,i,j,k,l)\
        (var=CreateWindowEx(a,b,c,d,e,f,g,h,i,j,k,l), \
        SendMessage(var, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)true), \
        var)
此宏的第一个参数是分配给它的
HWND
变量的名称。用法示例如下:

HWND hwnd = CrWinDef(hwnd, ... ); //arguments a through l
扩展至:

HWND hwnd = (hwnd = CreateWindowEx(a,b,c,d,e,f,g,h,i,j,k,l),
                    SendMessage(hwnd, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)true), 
                    hwnd);
请注意,如果不想将结果赋给值,这将不起作用,因此必须有两个宏:
CrWinDef
crwindefrat
或类似的宏


请使用常规函数。

宏不是函数;它们是预处理器指令。请尝试在使用宏文本时出现的位置逐字替换宏文本。你真的想要一个
return
吗?有没有理由
CrWinDef
不能成为函数?是的,我想要返回那个HWND。我知道函数通常用于返回值,但我确实懒得编写所有数据类型。我现在就这么做了,但我仍然有兴趣了解这样的事情是否可行。除了您可能在Windows上,您可以将宏安排为一个
内联
函数。但不幸的是,微软不支持旧标准(C99);它只支持四分之一世纪前的标准(C89/C90)。我可以在这里向您推荐我的帖子!!:我该如何定义返回类型?@Dan你不能。没有什么可声明的返回类型。宏只是文本替换。您必须使用函数才能定义返回类型。或者使用GNU编译器扩展。不过,这可能不是OP的选择。