如何防止宏在施法时隐藏'const'(C)

ide*_*n42 3 c macros casting constants

我有一个宏,它需要2个参数,一个值被修改,并得到一个我必须投射的偏移量.

#define MY_MACRO(dst, src) \
    do_something((char *)dst + offset, (char * )src + offset)
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,dst将进行修改,但是如果值为const,则强制转换(char *)将隐藏此值.

但是,我不希望这个宏默默地隐藏const成员.

static void my_function(const float *a, const float *b)
{
    MY_MACRO(a, b);  /* <-- this should warn because 'a' is const */
}
Run Code Online (Sandbox Code Playgroud)

我想知道是否有一种很好的方法可以确保宏中的变量不会隐藏const.

将示例解决方案移至自己的答案 - /sf/answers/1755107581/

Leu*_*nko 5

什么是你不能用const类型做的事情?分配给他们.因此,如何让编译器注意我们不应该const在这个位置使用指针?尝试通过他们分配!

在定义中添加一行:

#define MY_MACRO(dst, src) \
    ((void)(0 ? ((void)(*(dst) = *(dst)), *(src) = *(src)) : 0), \
    do_something((char *)dst + offset, (char * )src + offset))
Run Code Online (Sandbox Code Playgroud)

因为0 ? ...,插入的行实际上永远不会做任何事情(并且使用void强制转换它也不应该触发警告),但它是一个C级表达式,这意味着编译器必须在优化开始之前检查它; 它从未运行的事实,没有任何影响,并且在代码生成之前将被删除并不意味着它允许跳过类型检查.只有指向非const的指针才能通过.

分配的值来自同一个指针,因此它可以用于任何类型; 由于该行永远不会运行,因此从名称的多个外观中我们不会有任何多重评估问题.使用?:而不是if手段我们可以将它放在逗号表达式中,以防do_something需要返回值.