【问题标题】:How to implement C macro with assert如何用断言实现 C 宏
【发布时间】:2019-08-20 18:42:04
【问题描述】:

我在做一个 C 项目,它通过使用宏实现了一种多态性

void method1Instrumentation(void*);
bool method2Instrumentation(void*);
bool method3Instrumentation(void*);

#define method1(arg) method1Instrumentation(arg)
#define method2(arg) method2Instrumentation(arg)
#define method3(arg) method32Instrumentation(arg)

对于method1Instrumentation, method2Instrumentation, method3Instrumentation 中的每一个,都有几个实现。基于内部配置,编译器“选择”适当的函数。 我(可能)无法更改给定的设计。 但我需要将asserts 添加到method*。

工作正常

#define method1(arg) assert(arg == NULL) method1Instrumentation(arg)

不起作用(编译问题)

#define method2(arg) assert(arg == null) method2Instrumentation(arg)

由于原始代码有以下调用而出现问题

if(method2(arg))
{
}

我应该如何根据我的限制添加assets?

【问题讨论】:

  • 您打算声明method1Instrumentation 3 次吗?还是应该是 2 和 3?
  • 什么是null,应该是NULL?
  • "我应该如何添加assets?"应该是assert。
  • 如果if声明arg == null会发生什么?
  • 您不应该断言 arg not 为空吗?

标签: c macros assert


【解决方案1】:

使用comma operator 将assert 和函数调用组合成一个表达式。此外,将其括在括号中以防止在与其他运算符组合时出现运算符优先级问题。

#define method1(arg) (assert(arg != NULL), method1Instrumentation(arg))

【讨论】:

  • 不会是 && 因为 methodXIstrumentation 返回 bool 并且不需要第二个参数?
  • @Mario The Spoon,你是说不是逗号?不,因为assert 返回void。
  • @MarioTheSpoon 没有指定assert()的返回值。
  • ok 没注意到,但是if(method2(xxx)的编译不会也失败吧?
  • 不,为什么会这样?不使用逗号运算符左操作数的返回值。
【解决方案2】:

为了克服宏观上的丑陋,我会提出以下建议:

编辑使用 assert() 如评论中指出的那样;

#include <stdio.h>
#include <stdbool.h>

bool method1( void* data );
bool method2( void* data );

typedef bool (*methodPointer)(void*);

bool assertAndCall( void* data, methodPointer );

#define call1( arg )  assertAndCall( arg, method1 )
#define call2( arg )  assertAndCall( arg, method2 )


bool method1( void* data )
{
    printf("method1\n");
}

bool method2(void* data )
{
    printf("method2\n");
}

bool assertAndCall( void* data, methodPointer mp )
{
    assert( arg == null );

    mp( data );
}


int main()
{
    call1( "test ");
    call2( "test" );
    call1( NULL );

    return 0;
}

我知道,还有很多宏,还有更好的解决方案,但我想玩玩,,,

【讨论】:

  • 您不会触发标准 assert() 宏通常产生的任何错误。您也不像 assert() 那样依赖于 NDEBUG 宏。
猜你喜欢
  • 2010-10-22
  • 1970-01-01
  • 2016-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-06
相关资源
最近更新 更多