Dev Notes

Software Development Resources by David Egan.

C++ error ambiguating new declaration


C++
David Egan

If you receive a C++ compiler error message that includes the words “ambiguating new declaration”, check that you have the correct return type in your function declaration and definition.

Error Message

g++ -W -Wall -std=c++17 -o bin/main IntArray.cpp main.cpp
IntArray.cpp: In function ‘void mySwap(IntArray&, IntArray&)’:
IntArray.cpp:77:37: error: ambiguating new declaration of ‘void mySwap(IntArray&, IntArray&)’
 void mySwap(IntArray& a, IntArray& b)
                                     ^
In file included from IntArray.cpp:1:0:
IntArray.h:28:19: note: old declaration ‘IntArray& mySwap(IntArray&, IntArray&)’
  friend IntArray& mySwap(IntArray& a, IntArray& b);
                   ^

Cause

// IntArray.h
...
// wrong return type!
friend IntArray& mySwap(IntArray& a, IntArray& b);

// IntArray.cpp
...
void swap(IntArray& a, IntArray& b)
{
	std::swap(a.m_ptr, b.m_ptr);
	std::swap(a.m_size, b.m_size);
}

If you’re relatively new to C++ (or maybe just tired) you might miss this. It may not seem like the most obvious error message, but the caret in the second error really pinpoints the issue.

In this case, the compiler has read the function declaration/definition in the file IntArray.cpp and spotted a problem: “error: ambiguating new declaration…”.

The declaration is incompatible with the declaration in the header file because the return type differs. The first error uses the word “new” because it can see the declaration has already been made (in the header file). This is not necessarily a problem - as function overloading involves re-declaring a function with different parameter types. However in this case, the return type differs - this is not part of function overloading, so the declarations differ and the compiler can’t make sense of what you need.

Cognition, Attention & Debugging

It’s interesting that obvious bugs like this can trip you up.

I think viewing the function declaration and definition at the same time helps. If the two files are in different tabs, you’re relying on your memory to reliably take a snapshot of the definition/declaration as you switch between files. I suspect that this is less reliable in terms of spotting bugs than viewing the header and implementation files side by side.


comments powered by Disqus