将指向putchar的指针传递给接收int(*)(int)的函数

时间:2011-12-18 14:47:44

标签: c

我想知道将指向putchar的指针或任何其他可以作为宏实现的标准函数传递给接受函数指针的函数是否有任何问题。以下是我正在做的一个例子。

#include <stdio.h>

static int print(const char *s, int (*printc)(int))
{
        int c;

        while (*s != '\0') {
                if ((c = printc(*s++)) < 0)
                        return c;
        }
        return printc('\n');
}

int main(void)
{
        print("Hello, world", putchar);
        return 0;
}

我在使用GNU / Linux下的GCC和Clang以及OpenBSD下的GCC编译时没有任何问题。我想知道它是否会在其他所有符合标准的实现中具有相同的行为,因为putchar可以实现为宏。我已经搜索了标准,特别是关于函数指针和putchar的部分,并且无法找到任何指定这是否合法的内容。

感谢。

3 个答案:

答案 0 :(得分:6)

继我与@pmg的评论讨论之后,我找到了标准的相关部分(C99,7.1.4第1页):

  

...允许获取库函数的地址,即使它也被定义为   一个宏。 161)

     

<小时/>    161)这意味着实现应为每个库函数提供实际函数,即使它还为该函数提供宏。

答案 1 :(得分:2)

这是合法的,因为它指的是库函数,而不是宏。当它被定义为宏时,该宏接受一个参数,因此没有括号的putchar不会引用它。 这是一个使用宏来内联函数的实例,由于编译器支持内联,因此不应该将其视为良好实践。

答案 2 :(得分:2)

当宏的标识符后跟一个左括号(时,宏才会被“调用”。否则,将调用/使用相同名称的实际功能。

#include <stdio.h>
#define macro(x) 42
int (macro)(int x) { return x; }
int main(void) {
    printf("%d %d\n", macro(1), (macro)(1));
}

函数定义具有“额外”括号以防止宏被扩展

请参阅在ideone上运行的代码:http://ideone.com/UXvjX