这两个宏之间有什么区别吗?

时间:2019-07-04 22:14:30

标签: c c-preprocessor

我发现这两个宏之间没有什么区别,除了第一个宏中的括号。

是可读性问题还是处理操作员优先级的方法?

#define TAM_ARRAY(a) (sizeof(a)/sizeof(*a))
#define TAM_ARRAY2(a) sizeof(a)/sizeof(*a)

3 个答案:

答案 0 :(得分:7)

是的,有区别。需要使用括号,以便将宏的结果作为单个表达式求值,而不是与使用宏的周围上下文混合在一起。

该程序的输出:

#include <stdio.h>

#define TAM_ARRAY(a) (sizeof(a)/sizeof(*a))
#define TAM_ARRAY2(a) sizeof(a)/sizeof(*a)

int main(void)
{
    int x[4];
    printf("%zu\n", 13 % TAM_ARRAY (x));
    printf("%zu\n", 13 % TAM_ARRAY2(x));
}

是,在int是四个字节的C实现中:

1
3

因为:

  • 13 % TAM_ARRAY (x)替换为13 % (sizeof(x)/sizeof(*x))13 % (sizeof(x) / sizeof(*x))分组为13 % (16 / 4),其结果为13 % 4,然后是1,然后是13 % TAM_ARRAY2(x)。 / li>
  • 13 % sizeof(x)/sizeof(*x)替换为(13 % sizeof(x)) / sizeof(*x)(13 % 16) / 4分组为13 / 4,其结果为3,然后是TAM_ARRAY,然后是a。 / li>

沿着这些行,#define TAM_ARRAY(a) (sizeof(a)/sizeof(*(a))) 最好在add_action( 'admin_head-post.php', '_my_reset_image_insert_settings' ); add_action( 'admin_head-post-new.php', '_my_reset_image_insert_settings' ); function _my_reset_image_insert_settings() { ?> <script> if ( typeof setUserSetting !== 'undefined' ) { //setUserSetting( 'align', 'none' ); // none || left || center || right setUserSetting( 'imgsize', 'large' ); // thumbnail || medium || large || full //setUserSetting( 'urlbutton', 'none' ); // none || file || post } </script> <?php } 的第二个实例周围加上括号:

edgesIgnoringSageArea(.all)

答案 1 :(得分:3)

在代码翻译的早期阶段,宏会在文本上被替换。除非明确预期会有副作用,否则在宏扩展和宏扩展本身(如果是表达式)中完全括住宏参数非常重要。

在发布的情况下,您不太可能遇到问题,因为很少有运算符具有更高的优先级,并且可能不会在宏扩展周围使用它们,但这是一个病理示例:

  • TAM_ARRAY(a)["abcd"]扩展为(sizeof(a)/sizeof(*a))["abcd"],而
  • TAM_ARRAY2(a)["abcd"]扩展为sizeof(a)/sizeof(*a)["abcd"],与sizeof(a) / (sizeof(*a)["abcd"])等效。

但是请注意,像宏%这样的具有相同优先级的运算符肯定会引起问题,如Eric Postpischil的答案所述。

还请注意,a也应加括号:

#define TAM_ARRAY(a) (sizeof(a) / sizeof(*(a)))

答案 2 :(得分:2)

宏的工作方式是在编译时将代码“交换出去”。 所以像

#define ADD(i, j) i + j
int k = ADD(1, 2) * 3 

将被视为:int k = 1 + (2 * 3)

#define ADD(i, j) (i + j)
int k = ADD(1, 2) * 3

将被视为:int k = (1 + 2) * 3

因此,由于操作员的优先级,可能有两个宏。