有没有办法提供一个宏函数来返回不同类型的值,包括啥?
Posted
技术标签:
【中文标题】有没有办法提供一个宏函数来返回不同类型的值,包括啥?【英文标题】:Is there a way to provide a single macro function to return values of different types including nothing?有没有办法提供一个宏函数来返回不同类型的值,包括什么? 【发布时间】:2016-01-01 10:58:35 【问题描述】:我创建了以下宏来锁定互斥体并返回(从调用此宏的函数中)以防锁定尝试失败。目前我已将其缩小到 2 个宏 - 一个用于从返回值的函数返回,与类型无关,另一个用于从不返回任何内容的函数返回(即 void)。
宏之外的代码(下)仅用于说明,与宏将用于的实际生产代码几乎没有关系。
#define MUTEX_LOCK()\
\
if (pthread_mutex_lock(&mutex) != 0)\
\
printf("Failed to lock mutex.\n");\
return;\
\
#define MUTEX_LOCK_RVAL(err_val)\
\
if (pthread_mutex_lock(&mutex) != 0)\
\
printf("Failed to lock mutex.\n");\
return err_val;\
\
void vfunc()
printf("\nIn vfunc()\n");
MUTEX_LOCK();
printf("\nOut of vfunc()\n");
UINT16 uint16func()
printf("\nIn uint16func()\n");
MUTEX_LOCK_RVAL(0);
printf("\nOut of uint16func()\n");
return 9;
CHAR* errstr = "Hoo boy!";
CHAR* strfunc()
printf("\nIn strfunc()\n");
MUTEX_LOCK_RVAL(errstr);
printf("\nOut of strfunc()\n");
return NULL;
有没有办法将这些简化为一个宏,可以在返回值的函数中使用,也可以在 void 中使用。
【问题讨论】:
包含返回的类似函数的宏......这真的很讨厌。算了,在调用点使用if (!my_lock()) return <whatever>;
,有适当的锁定功能。
可能使用例如variadic macros,但有一些警告。这真的会让你的代码的其他读者感到困惑(而“其他人”我会在一年左右的时间里将你包括在内)。
@JoachimPileborg 你认为调用会令人困惑,还是只有宏定义?如果只有后者,一些明智的 cmet 应该解决它,不是吗?
哦,当您将pthread_mutex_lock
的返回值与未初始化的局部变量 进行比较时,您当前的宏包含未定义的行为。实际上你根本不需要变量,我真的建议你考虑一下@Mat 在说什么,然后你可以有一个简单的宏。
你把打印放在了锁功能里,不用重复了。隐藏 return 语句不是如果唯一可以为您节省几次击键的事情。记住你写了一次代码,但读了很多次。如果这意味着您的函数的控制流已变得不可见,则保存几个字符是个坏主意。
【参考方案1】:
为了使其与 ANSI 兼容,我使用 return 和另一个简单的符号定义了宏,该符号的计算结果为 null 并清楚地表明它为 null。 即:
#define VOID_RET //This nulls the return value
#define MUTEX_LOCK(err_val)\
\
if (pthread_mutex_lock(&mutex) != 0)\
\
printf("Failed to lock mutex.\n");\
return err_val;\
\
void *mutex = NULL;
void vfunc(void)
printf("\nIn vfunc()\n");
MUTEX_LOCK(VOID_RET);
printf("\nOut of vfunc()\n");
UINT16 uint16func(void)
printf("\nIn uint16func()\n");
MUTEX_LOCK(0);
printf("\nOut of uint16func()\n");
return 9;
CHAR* errstr = "Hoo boy!";
CHAR* strfunc(void)
printf("\nIn strfunc()\n");
MUTEX_LOCK(errstr);
printf("\nOut of strfunc()\n");
return NULL;
我在 C11 和 C99 下测试了这段代码。
【讨论】:
无论如何,这比我的解决方案要好得多。【参考方案2】:据我从文档中可以看出,您可以删除不带参数的宏函数,因为您根本没有义务将参数传递给需要参数的宏函数。来自GNU GCC documentation:
您可以将宏参数留空;这不是错误 预处理器 [...]
对于多个参数,这很有趣:
你不能完全忽略论点;如果一个宏需要两个 参数,其顶层必须有一个逗号 参数列表。
给出这些例子:
min(, b) ==> (( ) < (b) ? ( ) : (b))
min(a, ) ==> ((a ) < ( ) ? (a ) : ( ))
min(,) ==> (( ) < ( ) ? ( ) : ( ))
min((,),) ==> (((,)) < ( ) ? ((,)) : ( ))
【讨论】:
我试过这个,但这不是有效的 ansi C(我用 -pedantic 和 -Werror 标志编译)。我收到错误空宏参数在 ISO C90 和 ISO C++98 中未定义。 @work.bin 你能告诉我你为什么要遵守这些旧标准吗?现在至少 C99 应该是默认的,IMO。 如您所愿!但是支持 C99 的编译器并不多。如果便携性是一个问题,那么您仅限于 C90。【参考方案3】:我能想到的唯一解决方案是:
#define MUTEX_LOCK( err_val )\
\
\
if (pthread_mutex_lock(&mutex) != 0)\
\
printf("Failed to lock mutex.\n");\
return err_val;\
\
\
int test_int()
MUTEX_LOCK( 1 );
return 0;
void test_void()
MUTEX_LOCK( ; );
return;
【讨论】:
不是特别优雅,但很聪明。这确实回答了我的问题,但我不确定我是否会使用它。以上是关于有没有办法提供一个宏函数来返回不同类型的值,包括啥?的主要内容,如果未能解决你的问题,请参考以下文章