带省略号的函数指针转换

8
请见以下程序:
#include <iostream>

typedef void (*fptr)(...);

void foo(fptr func) {
    (*func)(12);
}

void bar(int x) {
    std::cout << "bar : " << x << std::endl;
}

int main() {
    foo(fptr(bar));
}

这段代码在至少一个编译器上可以编译运行,并输出bar : 12。我在一些需要维护的旧代码中发现了这个,我想知道这是否安全/定义明确?
由于barfptr类型不匹配,所以唯一使其工作的方法是使用不安全的强制转换。我猜这取决于省略号-魔法内部的工作原理,因此是否有明确定义?

它在我的编译器上也可以使用整数,但是如果(只是为了好玩)你想要证明它有多么邪恶,将程序转换为使用浮点数运行...这在我的编译器上无法正常工作。 - Benj
我认为您甚至无法拥有与“fptr”签名匹配的合法函数,因为可变参数函数始终需要至少一个命名参数。因此,您可以定义类型并创建指针变量,但不能将任何有效值赋给它。 - Kerrek SB
@Kerrek:我刚刚也发现了这一点。在C++中定义这样的函数是合法的(在C语言中不是),但正如你所说,实际上无法访问这些参数。 - Björn Pollex
1个回答

10

这段代码的行为是未定义的。如果它能够工作只是因为偶然性,那么没有任何保证它会正常工作。对于转换后的函数指针,唯一安全可行的操作就是将其强制转回原始类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接