gpt4 book ai didi

c++ - 这是 Solaris Studio 中的一个错误吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:39:38 25 4
gpt4 key购买 nike

源代码(在问题的末尾)将引发我认为是 Solaris Studio(而不是其他编译器)上的错误处理。

为清楚起见,错误消息已重新格式化为新行:

"overload.cpp", line 44: Error:
runGenEntries<std::vector<int>>(const GenEntryRuleDriven<int>&, const std::vector<int>&)
and
runGenEntries<std::vector<int>>(const GenEntryRulesDriven<int>&, const std::vector<int>&)
have same extern name
"__1cNrunGenEntries4nDstdGvector4Cin0AJallocator4Ci_____6FrkTArk1_v_".
1 Error(s) detected.

请注意两个函数 runGenEntries 的第一个参数如何仅相差一个字符(Rule 末尾的“s”)

这似乎发生在第一个参数的类型:

const typename GenEntryRulesDrivenType<typename InputsType::value_type>::type

当第一个参数不是类型时不会发生:

const typename GenEntryRulesDriven<typename InputsType::value_type>

最终解析为相同的类型!

这是仅在 Solaris 上实现的一些晦涩的 C++ 规则的结果吗?或者这是一个 Solaris Studio 错误,当它破坏符号时?

完整来源

以下源代码可在任何编译器上编译。

定义将激活引发错误的代码,或者激活应该产生相同结果的代码(但这次没有错误):

#include <iostream>
#include <vector>

template<typename T>
struct GenEntryRulesDriven
{
void foo() const
{
}
};

template<typename T>
struct GenEntryRuleDriven
{
void bar() const
{
}
std::string toto; // to have a different size than GenEntryRulesDriven
};


template <typename T>
struct GenEntryRulesDrivenType
{
typedef GenEntryRulesDriven<T> type;
};

template <typename T>
struct GenEntryRuleDrivenType
{
typedef GenEntryRuleDriven<T> type;
};

#if 1 // Gives an error

template <typename InputsType>
void runGenEntries(const typename GenEntryRulesDrivenType<
typename InputsType::value_type>::type &genEntry,
const InputsType& inputs)
{
genEntry.foo();
}

template <typename InputsType>
void runGenEntries(const typename GenEntryRuleDrivenType<
typename InputsType::value_type>::type &genEntry,
const InputsType& inputs)
{
genEntry.bar();
}

#else // No error but same types as above!

template <typename InputsType>
void runGenEntries(const typename GenEntryRulesDriven<
typename InputsType::value_type> &genEntry,
const InputsType& inputs)
{
genEntry.foo();
}

template <typename InputsType>
void runGenEntries(const typename GenEntryRuleDriven<
typename InputsType::value_type> &genEntry,
const InputsType& inputs)
{
genEntry.bar();
}

#endif

int
main()
{
std::vector<int> v;
GenEntryRulesDriven<int> rulesDriven;
runGenEntries(rulesDriven, v);

GenEntryRuleDriven<int> ruleDriven;
runGenEntries(ruleDriven, v);

return 0;
}

此代码是在以下平台上编译的:

bash$ uname -a
SunOS pegasus 5.10 Generic_118855-33 i86pc i386 i86pc
bash$ CC -V
CC: Sun C++ 5.10 SunOS_i386 128229-07 2010/03/24

最佳答案

简答

简短回答:这似乎是“无法修复”的错误 6532605(我看到它在许多谷歌搜索中被引用,但我无法在 https://support.oracle.com/rs?type=bug&id=6532605 上打开错误本身)。

Qt 开发人员采用的解决方法是将方法定义放在单独的编译单元(.cpp 文件)中。

背景

如果你分解 CC 提示的符号名称,你可以看到它正在编译一个 const __type_0& 参数作为第一个参数:

$ echo __1cNrunGenEntries4nDstdGvector4Cin0AJallocator4Ci_____6FrkTArk1_v_ | c++filt
void runGenEntries<std::vector<int> >(const __type_0&,const __type_0&)
$

在完全相同的 Solaris 10 盒子上使用 g++ 3.4.6, block 1 中的符号分解为:

runGenEntries<std, vector<int, std::allocator,<int>void> >(const GenEntryRuleDrivenType<int::value_type>::type(const GenEntryRuleDrivenType<int::value_type>&)&)
runGenEntries<std, vector<int, std::allocator,<int>void> >(const GenEntryRulesDrivenType<int::value_type>::type(const GenEntryRulesDrivenType<int::value_type>&)&)

为什么 Oracle 不能实现同样的事情是我无法理解的。

Qt 解决方法

引用此错误/解决方法的 Qt 代码是 here .

我们可以看到有两个用相似名称声明的函数:

Expression::Ptr DocFN::typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType);
Expression::Ptr IdFN::typeCheck(const StaticContext::Ptr &context, const SequenceType::Ptr &reqType);

并且每个都在自己的源代码(herehere)中编译以解决该错误。

不支持的解决方案:更改 ccfe 中的 mangling 选项

来自 here ,您也可以使用 -Qoption ccfe -abiopt=mangle6 进行编译。有了这些标志,代码编译成功,符号(demangled)为:

void runGenEntries<std::vector<int> >(const GenEntryRuleDrivenType<__type_0::value_type>::type&,const __type_0&)
void runGenEntries<std::vector<int> >(const GenEntryRulesDrivenType<__type_0::value_type>::type&,const __type_0&)

问题是 this compilation option is not supported ,正如 Steve Clamage 所写:

Finally, the compiler has a hidden option to fix all known mangling bugs unconditionally. We don't publicize the option because

  • It is unstable. Future patches or releases could change mangling if more bugs are found.
  • You might need to recompile all of the C++ code, including 3rd-party libraries, using this option.
  • If you create a library with this option, it might be incompatible with code compiled without the option.
  • As with all hidden options, it is subject to change or removal without notice.
  • We view this option as "use at your own risk".

If after all these caveats you still want to try the option, here it is:

-Qoption ccfe -abiopt=mangle6

Be sure to add it to every CC command, and recompile everything.

Fortunately, none of the C++ system libraries shipped with Solaris or Studio is affected by this bug or the hidden option, so you don't need to worry about different versions of those libraries.

关于c++ - 这是 Solaris Studio 中的一个错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22233320/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com