Это ошибка в Solaris Studio?

Источник (в конце вопроса) будет вызывать, как мне кажется, ошибку в 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 отличается только одним символом (‘s’ в конце правила)

Это, кажется, происходит, когда первый параметр имеет тип:

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

И не происходит, когда первый параметр вместо типа:

const typename GenEntryRulesDriven<typename InputsType::value_type>

Который решает тот же тип в конце концов!

Является ли это следствием неясного правила C ++, реализованного только в Solaris? Или это ошибка 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

5

Решение

Короткий ответ

Краткий ответ: это, похоже, «нефиксированная» ошибка 6532605 (я вижу, что на нее ссылаются многочисленные поиски в Google, но я не могу открыть саму ошибку на 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&)
$

С g ++ 3.4.6 на точно такой же коробке Solaris 10 символы из блока 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, на который ссылаются на эту ошибку / обходной путь: Вот.

Мы можем видеть, что есть две функции, объявленные с похожим именем:

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

И каждый компилируется в свой собственный источник (Вот а также Вот) чтобы обойти ошибку.

Неподдерживаемое решение: измените опцию искажения в ccfe

От Вот, Вы также можете скомпилировать с -Qoption ccfe -abiopt=mangle6, С этими флагами код успешно компилируется, а символы (размеченные):

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&)

Проблема в том, что эта опция компиляции не поддерживается, как написано Стивом Clamage:

Наконец, у компилятора есть скрытая опция, позволяющая безоговорочно исправлять все известные ошибки. Мы не публикуем опцию, потому что

  • Это нестабильно. Будущие исправления или выпуски могут изменить искажение, если будет найдено больше ошибок.
  • Возможно, вам придется перекомпилировать весь код C ++, включая сторонние библиотеки, используя эту опцию.
  • Если вы создаете библиотеку с этой опцией, она может быть несовместима с кодом, скомпилированным без этой опции.
  • Как и все скрытые параметры, он может быть изменен или удален без уведомления.
  • Мы рассматриваем эту опцию как «использовать на свой страх и риск».

Если после всех этих предостережений вы все еще хотите попробовать вариант, вот он:

-Qoption ccfe -abiopt=mangle6

Обязательно добавьте его в каждую команду CC и перекомпилируйте все.

К счастью, ни одна из системных библиотек C ++, поставляемых с Solaris или Studio, не подвержена этой ошибке или скрытому параметру, поэтому вам не нужно беспокоиться о разных версиях этих библиотек.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]