Clang error: conditional expression is ambiguous; A and B can be converted to several common types (err_conditional_ambiguous_ovl)

From emmtrix Wiki
Jump to navigation Jump to search
Text
error: conditional expression is ambiguous;
A and B
types
can be converted to several common types

Type Error
Category Semantic Issue
Internal Id err_conditional_ambiguous_ovl
Internal Message conditional expression is ambiguous; %diff{$ and $|types}0,1 can be converted to several common types
Regular Expression (?:error|fatal error)\: conditional expression is ambiguous; (?:(.*?) and (.*?)|types) can be converted to several common types
First Commit 2009-04-16 1a99f441e64c Fix a crash bug when comparing overload quality of conversion operators with conversion constructors...

Description

The error is issued by the Clang compiler when it encounters a situation where a conditional expression, specifically the ternary ? : operator, is used with operands that lead to ambiguity in determining a common type for the expression to be evaluated to. This typically occurs when both operands of the conditional expression are of types that can be converted to more than one common type, and the compiler cannot unambiguously decide which type to use for the resulting value of the conditional expression. In C++, when an object of a class type has more than one user-defined conversion function that could be used to convert it to a built-in type, and those conversion functions lead to multiple possible common types for the conditional expression, this error is triggered. The resolution of the conditional expression's type is essential for the correct execution of the program, as the type determines how the expression can be used further in the code. This error, therefore, alerts the programmer to a need for disambiguation, either by explicitly casting one or both operands to a common type or by providing additional context that would help the compiler determine the intended common type.  
AI Generated

Example

In the following example, two struct types, A and B, are defined, each with two user-defined conversion functions. These functions enable objects of these types to be implicitly converted either to an int or a double. The example attempts to use these two types within a ternary conditional expression. This usage leads to ambiguity because the compiler cannot determine a common type for the ternary expression's result. Given that both A() and B() can be converted to both int and double, the compiler is unable to decide which conversion to use without further guidance, thereby triggering the error message. This scenario exemplifies a situation where the capability of an object to be converted to more than one type leads to ambiguity in the context of a ternary conditional operation.  
AI Generated


Flags -xc++ -std=c++11

[Try out in Compiler Explorer]

Source
struct A { operator int() { return 0; } operator double() { return 0.0; } };
struct B { operator int() { return 0; } operator double() { return 0.0; } };

int main() {
  // A() and B() can both be converted to int or double
  return true ? A() : B();
}
Compiler Output
<source>:6:15: error: conditional expression is ambiguous; 'A' and 'B' can be converted to several common types


Clang Internals (17.0.6)

Git Commit Message

Fix a crash bug when comparing overload quality of conversion operators with conversion constructors.
Remove an atrocious amount of trailing whitespace in the overloaded operator mangler. Sorry, couldn't help myself.
Change the DeclType parameter of Sema::CheckReferenceInit to be passed by value instead of reference. It wasn't changed anywhere.
Let the parser handle C++'s irregular grammar around assignment-expression and conditional-expression.
And finally, the reason for all this stuff: implement C++ semantics for the conditional operator. The implementation is complete except for determining lvalueness.

llvm-svn: 69299

Used in Clang Sources

This section lists all occurrences of the diagnostic within the Clang's codebase. For each occurrence, an auto-extracted snipped from the source code is listed including key elements like control structures, functions, or classes. It should illustrate the conditions under which the diagnostic is activated.

clang/lib/Sema/SemaExprCXX.cpp (line 6266)

/// Try to find a common type for two according to C++0x 5.16p5.
///
/// This is part of the parameter validation for the ? operator. If either
/// value operand is a class type, overload resolution is used to find a
/// conversion to a common type.
static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS, SourceLocation QuestionLoc) {
  // ...
  case OR_Ambiguous:
    Self.Diag(QuestionLoc, diag::err_conditional_ambiguous_ovl) << LHS.get()->getType() << RHS.get()->getType() << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();