2017-10-28 165 views
0

我目前正在学习如何使用OpenCL进行编码,并决定运行一些示例代码。我已下载英特尔SDK,Microsoft Visual Studio 2017及其相关插件。Microsoft Visual Studio上的OpenCL:模板不能声明为具有C链接

当我尝试运行某个程序时,出现了与从Intel下载的%iNTELOCLSDKROOT依赖项中包含的其中一个“附加依赖性”文件有关的问题。我尝试构建解决方案时遇到的错误是模板不能声明为具有C链接(C2894)。这个错误完全位于一个名为xtr1common的文件中。我尝试将文件名从host.cpp更改为host.c,它删除了C2894错误,但随后出现语法错误,因为它明显不是C写的。如何解决?我很困惑,因为我非常怀疑英特尔在他们的代码中存在错误,以及我最不可能注意到的其他事情。为防万一代码中可能存在错误,我将它包含在下面。欢迎任何建议。

// xtr1common internal header 
#pragma once 
#ifndef _XTR1COMMON_ 
#define _XTR1COMMON_ 
#ifndef RC_INVOKED 
#include <yvals.h> 

#pragma pack(push,_CRT_PACKING) 
#pragma warning(push,_STL_WARNING_LEVEL) 
#pragma warning(disable: _STL_DISABLED_WARNINGS) 
#pragma push_macro("new") 
#undef new 

_STD_BEGIN 
    // STRUCT _Nil 
struct _Nil 
    { // empty struct, for unused argument types 
    }; 

    // TEMPLATE CLASS integral_constant 
template<class _Ty, 
    _Ty _Val> 
    struct integral_constant 
    { // convenient template for integral constant types 
    static constexpr _Ty value = _Val; 

    using value_type = _Ty; 
    using type = integral_constant; 

    constexpr operator value_type() const _NOEXCEPT 
     { // return stored value 
     return (value); 
     } 

    constexpr value_type operator()() const _NOEXCEPT 
     { // return stored value 
     return (value); 
     } 
    }; 

    // ALIAS TEMPLATE bool_constant 
template<bool _Val> 
    using bool_constant = integral_constant<bool, _Val>; 

using true_type = bool_constant<true>; 
using false_type = bool_constant<false>; 

    // TEMPLATE CLASS enable_if 
template<bool _Test, 
    class _Ty = void> 
    struct enable_if 
    { // type is undefined for assumed !_Test 
    }; 

template<class _Ty> 
    struct enable_if<true, _Ty> 
    { // type is _Ty for _Test 
    using type = _Ty; 
    }; 

template<bool _Test, 
    class _Ty = void> 
    using enable_if_t = typename enable_if<_Test, _Ty>::type; 

    // TEMPLATE CLASS conditional 
template<bool _Test, 
    class _Ty1, 
    class _Ty2> 
    struct conditional 
    { // type is _Ty2 for assumed !_Test 
    using type = _Ty2; 
    }; 

template<class _Ty1, 
    class _Ty2> 
    struct conditional<true, _Ty1, _Ty2> 
    { // type is _Ty1 for _Test 
    using type = _Ty1; 
    }; 

template<bool _Test, 
    class _Ty1, 
    class _Ty2> 
    using conditional_t = typename conditional<_Test, _Ty1, _Ty2>::type; 

    // TEMPLATE CLASS is_same 
template<class _Ty1, 
    class _Ty2> 
    struct is_same 
     : false_type 
    { // determine whether _Ty1 and _Ty2 are the same type 
    }; 

template<class _Ty1> 
    struct is_same<_Ty1, _Ty1> 
     : true_type 
    { // determine whether _Ty1 and _Ty2 are the same type 
    }; 

template<class _Ty, 
    class _Uty> 
    constexpr bool is_same_v = is_same<_Ty, _Uty>::value; 

    // TEMPLATE CLASS remove_const 
template<class _Ty> 
    struct remove_const 
    { // remove top level const qualifier 
    using type = _Ty; 
    }; 

template<class _Ty> 
    struct remove_const<const _Ty> 
    { // remove top level const qualifier 
    using type = _Ty; 
    }; 

template<class _Ty> 
    using remove_const_t = typename remove_const<_Ty>::type; 

    // TEMPLATE CLASS remove_volatile 
template<class _Ty> 
    struct remove_volatile 
    { // remove top level volatile qualifier 
    using type = _Ty; 
    }; 

template<class _Ty> 
    struct remove_volatile<volatile _Ty> 
    { // remove top level volatile qualifier 
    using type = _Ty; 
    }; 

template<class _Ty> 
    using remove_volatile_t = typename remove_volatile<_Ty>::type; 

    // TEMPLATE CLASS remove_cv 
template<class _Ty> 
    struct remove_cv 
    { // remove top level const and volatile qualifiers 
    using type = _Ty; 
    }; 

template<class _Ty> 
    struct remove_cv<const _Ty> 
    { // remove top level const and volatile qualifiers 
    using type = _Ty; 
    }; 

template<class _Ty> 
    struct remove_cv<volatile _Ty> 
    { // remove top level const and volatile qualifiers 
    using type = _Ty; 
    }; 

template<class _Ty> 
    struct remove_cv<const volatile _Ty> 
    { // remove top level const and volatile qualifiers 
    using type = _Ty; 
    }; 

template<class _Ty> 
    using remove_cv_t = typename remove_cv<_Ty>::type; 

    // TEMPLATE CLASS _Is_integral 
template<class _Ty> 
    struct _Is_integral 
     : false_type 
    { // determine whether _Ty is integral 
    }; 

template<> 
    struct _Is_integral<bool> 
     : true_type 
    { // determine whether _Ty is integral 
    }; 

template<> 
    struct _Is_integral<char> 
     : true_type 
    { // determine whether _Ty is integral 
    }; 

template<> 
    struct _Is_integral<unsigned char> 
     : true_type 
    { // determine whether _Ty is integral 
    }; 

template<> 
    struct _Is_integral<signed char> 
     : true_type 
    { // determine whether _Ty is integral 
    }; 

#ifdef _NATIVE_WCHAR_T_DEFINED 
template<> 
    struct _Is_integral<wchar_t> 
     : true_type 
    { // determine whether _Ty is integral 
    }; 
#endif /* _NATIVE_WCHAR_T_DEFINED */ 

template<> 
    struct _Is_integral<char16_t> 
     : true_type 
    { // determine whether _Ty is integral 
    }; 

template<> 
    struct _Is_integral<char32_t> 
     : true_type 
    { // determine whether _Ty is integral 
    }; 

template<> 
    struct _Is_integral<unsigned short> 
     : true_type 
    { // determine whether _Ty is integral 
    }; 

template<> 
    struct _Is_integral<short> 
     : true_type 
    { // determine whether _Ty is integral 
    }; 

template<> 
    struct _Is_integral<unsigned int> 
     : true_type 
    { // determine whether _Ty is integral 
    }; 

template<> 
    struct _Is_integral<int> 
     : true_type 
    { // determine whether _Ty is integral 
    }; 

template<> 
    struct _Is_integral<unsigned long> 
     : true_type 
    { // determine whether _Ty is integral 
    }; 

template<> 
    struct _Is_integral<long> 
     : true_type 
    { // determine whether _Ty is integral 
    }; 

template<> 
    struct _Is_integral<unsigned long long> 
     : true_type 
    { // determine whether _Ty is integral 
    }; 

template<> 
    struct _Is_integral<long long> 
     : true_type 
    { // determine whether _Ty is integral 
    }; 

    // TEMPLATE CLASS is_integral 
template<class _Ty> 
    struct is_integral 
     : _Is_integral<remove_cv_t<_Ty>>::type 
    { // determine whether _Ty is integral 
    }; 

template<class _Ty> 
    constexpr bool is_integral_v = is_integral<_Ty>::value; 

    // TEMPLATE CLASS _Is_floating_point 
template<class _Ty> 
    struct _Is_floating_point 
     : false_type 
    { // determine whether _Ty is floating point 
    }; 

template<> 
    struct _Is_floating_point<float> 
     : true_type 
    { // determine whether _Ty is floating point 
    }; 

template<> 
    struct _Is_floating_point<double> 
     : true_type 
    { // determine whether _Ty is floating point 
    }; 

template<> 
    struct _Is_floating_point<long double> 
     : true_type 
    { // determine whether _Ty is floating point 
    }; 

    // TEMPLATE CLASS is_floating_point 
template<class _Ty> 
    struct is_floating_point 
     : _Is_floating_point<remove_cv_t<_Ty>>::type 
    { // determine whether _Ty is floating point 
    }; 

template<class _Ty> 
    constexpr bool is_floating_point_v = is_floating_point<_Ty>::value; 

    // TEMPLATE CLASS is_arithmetic 
template<class _Ty> 
    struct is_arithmetic 
     : bool_constant<is_integral<_Ty>::value 
      || is_floating_point<_Ty>::value> 
    { // determine whether _Ty is an arithmetic type 
    }; 

template<class _Ty> 
    constexpr bool is_arithmetic_v = is_arithmetic<_Ty>::value; 

    // TEMPLATE CLASS remove_reference 
template<class _Ty> 
    struct remove_reference 
    { // remove reference 
    using type = _Ty; 
    }; 

template<class _Ty> 
    struct remove_reference<_Ty&> 
    { // remove reference 
    using type = _Ty; 
    }; 

template<class _Ty> 
    struct remove_reference<_Ty&&> 
    { // remove rvalue reference 
    using type = _Ty; 
    }; 

template<class _Ty> 
    using remove_reference_t = typename remove_reference<_Ty>::type; 

_STD_END 
#pragma pop_macro("new") 
#pragma warning(pop) 
#pragma pack(pop) 
#endif /* RC_INVOKED */ 
#endif /* _XTR1COMMON_ */ 

/* 
* Copyright (c) by P.J. Plauger. All rights reserved. 
* Consult your license regarding permissions and restrictions. 
V6.50:0009 */ 
+0

对不起,我的意思是这些错误*位于单个文件xtr1common中。总共有52个。 –

+0

问题不在于此代码中,而在于它包含的地方。你有没有'extern“C”{#include }'?由于C语言中没有模板,所以模板不能有C链接。 –

+0

当我尝试在此处的intel示例页面中构建简单示例时,出现上述错误消息> https://software.intel.com/en-us/intel-opencl-support/code-samples。例如,我刚刚加载了来自Buffer的示例>用于Windows Image的高级OpenCL Samples。只要我建立它,相同的消息从之前出现......模板不能被声明为“c”链接。我查看了代码,没有看到您描述的任何内容。 :( –

回答

0

我发现这个头文件#includes xtr1common,并在程序中有外部C.这可能是问题的根源吗?自从使用SDK从英特尔下载以来,我一直没有改变它。

/* xtgmath.h internal header */ 

#if defined(__cplusplus) 
#pragma once 
#ifndef _XTGMATH 
#define _XTGMATH 
#ifndef RC_INVOKED 
#include <cstdlib> 
#include <xtr1common> 

#pragma pack(push,_CRT_PACKING) 
#pragma warning(push,_STL_WARNING_LEVEL) 
#pragma warning(disable: _STL_DISABLED_WARNINGS) 
#pragma push_macro("new") 
#undef new 

_STD_BEGIN 
template<class _Ty1, 
    class _Ty2> 
    using _Common_float_type_t = 
     conditional_t<is_same<_Ty1, long double>::value || is_same<_Ty2, long double>::value, long double, 
     conditional_t<is_same<_Ty1, float>::value && is_same<_Ty2, float>::value, float, 
     double>>; // find type for two-argument math function 
_STD_END 

#define _CRTDEFAULT 
#define _CRTSPECIAL _ACRTIMP 

#define _GENERIC_MATH1R(FUN, RET, CRTTYPE) \ 
extern "C" _Check_return_ CRTTYPE RET __cdecl FUN(_In_ double); \ 
template<class _Ty, \ 
    class = _STD enable_if_t< _STD is_integral<_Ty>::value>> inline \ 
    RET FUN(_Ty _Left) \ 
    { \ 
    return (_CSTD FUN(static_cast<double>(_Left))); \ 
    } 

#define _GENERIC_MATH1(FUN, CRTTYPE) \ 
    _GENERIC_MATH1R(FUN, double, CRTTYPE) 

#define _GENERIC_MATH1X(FUN, ARG2, CRTTYPE) \ 
extern "C" _Check_return_ CRTTYPE double __cdecl FUN(_In_ double, ARG2); \ 
template<class _Ty, \ 
    class = _STD enable_if_t< _STD is_integral<_Ty>::value>> inline \ 
    double FUN(_Ty _Left, ARG2 _Arg2) \ 
    { \ 
    return (_CSTD FUN(static_cast<double>(_Left), _Arg2)); \ 
    } 

#define _GENERIC_MATH2_CALL(FUN, CRTTYPE, CALL_OPT) \ 
extern "C" _Check_return_ CRTTYPE double CALL_OPT FUN(_In_ double, _In_ double); \ 
template<class _Ty1, \ 
    class _Ty2, \ 
    class = _STD enable_if_t< _STD is_arithmetic<_Ty1>::value && _STD is_arithmetic<_Ty2>::value>> inline \ 
    _STD _Common_float_type_t<_Ty1, _Ty2> FUN(_Ty1 _Left, _Ty2 _Right) \ 
    { \ 
    typedef _STD _Common_float_type_t<_Ty1, _Ty2> type; \ 
    return (_CSTD FUN(static_cast<type>(_Left), static_cast<type>(_Right))); \ 
    } 

#define _GENERIC_MATH2(FUN, CRTTYPE) \ 
    _GENERIC_MATH2_CALL(FUN, CRTTYPE, __cdecl) 

template<class _Ty1, 
    class _Ty2, 
    class = _STD enable_if_t< _STD is_arithmetic<_Ty1>::value && _STD is_arithmetic<_Ty2>::value>> inline 
    _STD _Common_float_type_t<_Ty1, _Ty2> pow(const _Ty1 _Left, const _Ty2 _Right) 
    { // bring mixed types to a common type 
    typedef _STD _Common_float_type_t<_Ty1, _Ty2> type; 
    return (_CSTD pow(static_cast<type>(_Left), static_cast<type>(_Right))); 
    } 

//_GENERIC_MATH1(abs, _CRTDEFAULT) // has integer overloads 
_GENERIC_MATH1(acos, _CRTDEFAULT) 
_GENERIC_MATH1(asin, _CRTDEFAULT) 
_GENERIC_MATH1(atan, _CRTDEFAULT) 
_GENERIC_MATH2(atan2, _CRTDEFAULT) 
_GENERIC_MATH1(ceil, _CRTSPECIAL) 
_GENERIC_MATH1(cos, _CRTDEFAULT) 
_GENERIC_MATH1(cosh, _CRTDEFAULT) 
_GENERIC_MATH1(exp, _CRTDEFAULT) 

_GENERIC_MATH1(fabs, _CRT_JIT_INTRINSIC) 

_GENERIC_MATH1(floor, _CRTSPECIAL) 
_GENERIC_MATH2(fmod, _CRTDEFAULT) 
_GENERIC_MATH1X(frexp, _Out_ int *, _CRTSPECIAL) 
_GENERIC_MATH1X(ldexp, _In_ int, _CRTSPECIAL) 
_GENERIC_MATH1(log, _CRTDEFAULT) 
_GENERIC_MATH1(log10, _CRTDEFAULT) 
//_GENERIC_MATH1(modf, _CRTDEFAULT)  // types must match 
//_GENERIC_MATH2(pow, _CRTDEFAULT) // hand crafted 
_GENERIC_MATH1(sin, _CRTDEFAULT) 
_GENERIC_MATH1(sinh, _CRTDEFAULT) 
_GENERIC_MATH1(sqrt, _CRTDEFAULT) 
_GENERIC_MATH1(tan, _CRTDEFAULT) 
_GENERIC_MATH1(tanh, _CRTDEFAULT) 

     // C99 MATH FUNCTIONS 

     // TEMPLATE FUNCTION fma 

inline float _Fma(float _Left, float _Middle, float _Right) 
    { // call float fma 
    return (_CSTD fmaf(_Left, _Middle, _Right)); 
    } 

inline double _Fma(double _Left, double _Middle, double _Right) 
    { // call double fma 
    return (_CSTD fma(_Left, _Middle, _Right)); 
    } 

inline long double _Fma(long double _Left, long double _Middle, 
    long double _Right) 
    { // call long double fma 
    return (_CSTD fmal(_Left, _Middle, _Right)); 
    } 

template<class _Ty1, 
    class _Ty2, 
    class _Ty3> inline 
    _STD _Common_float_type_t<_Ty1, _STD _Common_float_type_t<_Ty2, _Ty3>> 
    fma(_Ty1 _Left, _Ty2 _Middle, _Ty3 _Right) 
    { // bring mixed types to a common type 
    typedef _STD _Common_float_type_t<_Ty1, _STD _Common_float_type_t<_Ty2, _Ty3>> type; 
    return (_Fma((type)_Left, (type)_Middle, (type)_Right)); 
    } 

     // TEMPLATE FUNCTION remquo 

inline float _Remquo(float _Left, float _Right, int *_Pquo) 
    { // call float remquo 
    return (_CSTD remquof(_Left, _Right, _Pquo)); 
    } 

inline double _Remquo(double _Left, double _Right, int *_Pquo) 
    { // call double remquo 
    return (_CSTD remquo(_Left, _Right, _Pquo)); 
    } 

inline long double _Remquo(long double _Left, long double _Right, int *_Pquo) 
    { // call long double remquo 
    return (_CSTD remquol(_Left, _Right, _Pquo)); 
    } 

template<class _Ty1, 
    class _Ty2> inline 
    _STD _Common_float_type_t<_Ty1, _Ty2> 
    remquo(_Ty1 _Left, _Ty2 _Right, int *_Pquo) 
    { // bring mixed types to a common type 
    typedef _STD _Common_float_type_t<_Ty1, _Ty2> type; 
    return (_Remquo((type)_Left, (type)_Right, _Pquo)); 
    } 

_GENERIC_MATH1(acosh, _CRTSPECIAL) 
_GENERIC_MATH1(asinh, _CRTSPECIAL) 
_GENERIC_MATH1(atanh, _CRTSPECIAL) 
_GENERIC_MATH1(cbrt, _CRTSPECIAL) 
_GENERIC_MATH2(copysign, _CRTSPECIAL) 
_GENERIC_MATH1(erf, _CRTSPECIAL) 
_GENERIC_MATH1(erfc, _CRTSPECIAL) 
_GENERIC_MATH1(expm1, _CRTSPECIAL) 
_GENERIC_MATH1(exp2, _CRTSPECIAL) 
_GENERIC_MATH2(fdim, _CRTSPECIAL) 
//_GENERIC_MATH3(fma, _CRTSPECIAL) // hand crafted 
_GENERIC_MATH2(fmax, _CRTSPECIAL) 
_GENERIC_MATH2(fmin, _CRTSPECIAL) 
_GENERIC_MATH2(hypot, _CRTSPECIAL) 
_GENERIC_MATH1R(ilogb, int, _CRTSPECIAL) 
_GENERIC_MATH1(lgamma, _CRTSPECIAL) 
_GENERIC_MATH1R(llrint, long long, _CRTSPECIAL) 
_GENERIC_MATH1R(llround, long long, _CRTSPECIAL) 
_GENERIC_MATH1(log1p, _CRTSPECIAL) 
_GENERIC_MATH1(log2, _CRTSPECIAL) 
_GENERIC_MATH1(logb, _CRTSPECIAL) 
_GENERIC_MATH1R(lrint, long, _CRTSPECIAL) 
_GENERIC_MATH1R(lround, long, _CRTSPECIAL) 
_GENERIC_MATH1(nearbyint, _CRTSPECIAL) 
_GENERIC_MATH2(nextafter, _CRTSPECIAL) 
_GENERIC_MATH1X(nexttoward, _In_ long double, _CRTSPECIAL) 
_GENERIC_MATH2(remainder, _CRTSPECIAL) 
//_GENERIC_MATH2X(remquo, _CRTSPECIAL) // hand crafted 
_GENERIC_MATH1(rint, _CRTSPECIAL) 
_GENERIC_MATH1(round, _CRTSPECIAL) 
_GENERIC_MATH1X(scalbln, _In_ long, _CRTSPECIAL) 
_GENERIC_MATH1X(scalbn, _In_ int, _CRTSPECIAL) 
_GENERIC_MATH1(tgamma, _CRTSPECIAL) 
_GENERIC_MATH1(trunc, _CRTSPECIAL) 

#undef _CRTDEFAULT 
#undef _CRTSPECIAL 
#undef _GENERIC_MATH1R 
#undef _GENERIC_MATH1 
#undef _GENERIC_MATH1X 
#undef _GENERIC_MATH2_CALL 
#undef _GENERIC_MATH2 

#pragma pop_macro("new") 
#pragma warning(pop) 
#pragma pack(pop) 
#endif /* RC_INVOKED */ 
#endif /* _XTGMATH */ 
#endif /* defined(__cplusplus) */ 

/* 
* Copyright (c) by P.J. Plauger. All rights reserved. 
* Consult your license regarding permissions and restrictions. 
V6.50:0009 */