为什么cblas_dgemm和cblas_sgemm在函数指针数组中有不同的指针类型?

为什么cblas_dgemm和cblas_sgemm在函数指针数组中有不同的指针类型?,c,function-pointers,lapack,atlas,C,Function Pointers,Lapack,Atlas,我有一个函数指针数组,用于调用相应的cblas_xgemm(例如,ATLAS/cblas中的cblas_dgemm或cblas_sgemm等) 当我告诉它通过函数指针使用cblasdgemm时,效果非常好;使用适当的参数调用dgemm并返回正确的结果 但是,当我通过函数指针调用cblas\u sgemm时,我得到以下输出: ldc must be >= MAX(N,1): ldc=0 N=2Parameter 14 to routine cblas_sgemm was incorrect

我有一个函数指针数组,用于调用相应的
cblas_xgemm
(例如,ATLAS/cblas中的
cblas_dgemm
cblas_sgemm
等)

当我告诉它通过函数指针使用
cblasdgemm
时,效果非常好;使用适当的参数调用dgemm并返回正确的结果

但是,当我通过函数指针调用
cblas\u sgemm
时,我得到以下输出:

ldc must be >= MAX(N,1): ldc=0 N=2Parameter 14 to routine cblas_sgemm was incorrect
我已经编写了一个示例来演示这个问题。在没有函数指针的情况下调用
cblas\u sgemm
可以正常工作

特别注意以下gcc警告(另请参见上面链接的要点,其中包含完整的gcc输出):

如果我注释掉函数指针数组定义中的
cblas_sgemm
行,我不会得到这样的警告,即使是对于
cblas_dgemm
行。但这毫无意义,因为这两个函数应该具有相同的返回类型

以下是
cblas.h
中的相应行:

void cblas_sgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
                 const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
                 const int K, const float alpha, const float *A,
                 const int lda, const float *B, const int ldb,
                 const float beta, float *C, const int ldc);
void cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
                 const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
                 const int K, const double alpha, const double *A,
                 const int lda, const double *B, const int ldb,
                 const double beta, double *C, const int ldc);

那么是什么原因呢?它是否以某种方式从一个标题获取一个
xgemm
函数,从另一个标题获取另一个?或者我正在处理一些奇怪的函数指针问题?

您的问题似乎可以归结为这样一个事实:您试图从函数指针数组调用具有不同签名的函数。我自己从来没有试过,但从一点研究来看,这似乎是不可能的。这是有道理的,因为静态类型语言无法评估此操作的类型安全性

我看到过使用boost::variant和其他解决方法的建议,但由于您链接到的库不是我们的yown,我不确定购买这些选项是否有多大价值

如果您想证明或反驳,可以从测试程序中删除CBLA,只需实现一个具有多个签名方法的类,这些签名方法只在数据类型上有所不同


另一方面,主栏是一个主要的痛苦

你能展示一些代码吗?如果没有上下文,很难对抽象编译器错误进行评论。问题中有代码链接:你能解释你所说的签名是什么意思吗?我的理解是相同的返回类型和参数类型+数字=>相同的签名。是的,我同意。但是您的参数类型不同。看看beta。它在SGE函数中是一个浮点,在DGE函数中是双精度。我最近与BLAS合作过,我隐约记得这些函数使用的数据类型是D前缀(双精度)和S前缀(我猜是单精度,当你移植到C++时,它会变成浮点型)之间的差异。哦,天哪。我(以为)仔细阅读了那些论点清单。你完全正确。非常感谢你。
void cblas_sgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
                 const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
                 const int K, const float alpha, const float *A,
                 const int lda, const float *B, const int ldb,
                 const float beta, float *C, const int ldc);
void cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
                 const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
                 const int K, const double alpha, const double *A,
                 const int lda, const double *B, const int ldb,
                 const double beta, double *C, const int ldc);