Friend functions default parameters behavior

Hi all,
In the http://clang.debian.net/ project Sylvestre, Arthur and I are trying to rebuild Debian with clang. And we have the problems with default arguments in the friend methods. (http://clang.debian.net/status.php?version=3.4.2&key=WRONG_DEFAULT_DECLARATION). This issue affects 19 packages in the Debian rebuild.

In the process of the rebuild Debian packages we had created simple example which contains different behavior with gcc and clang. Please see below:

Simple example

int func1(int i, int j) { return i + j; }

class foo {
friend int func1(int i, int j = 0);
public:
int func();
};

int foo::func() { return func1(1); }

int main() {
foo a;
a.func();
return 0;
}

Clang compilation error:
test.cpp:8:12: error: friend declaration specifying a default argument must be the only declaration
friend int func1(int i, int j = 0);
^
test.cpp:1:5: note: previous declaration is here

int func1(int i, int j)
^

test.cpp:15:12: error: no matching function for call to ‘func1’
return func1(1);
^~~~~
test.cpp:1:5: note: candidate function not viable: requires 2 arguments, but 1 was provided

int func1(int i, int j)
^

2 errors generated.

The provided example successfully complies by gcc. So as it seems for the clang successfully compilation failed packages requires patches.

As I understand the following code is correct way to using default arguments with friend functions:

int func1(int i, int j = 0);

class foo {
friend int func1(int i, int j);

public:
int func();
};

int foo::func() { return func1(1); }

int main() {
foo a;
a.func();
return 0;
}

int func1(int i, int j) { return i + j; }

Even if clang seems to follow the C++ specification, I wonder if clang is not too strict here.
For example, this patch, to make sure that the code compiles with clang, I had to basically get ride of the default feature:
https://bugs.debian.org/cgi-bin/bugreport.cgi?msg=5;filename=gfan.diff;att=1;bug=755308
to be able to compile the code with clang without touching the API.

This is taken from clang source at the point where the error is emitted:

// C++11 [dcl.fct.default]p4: If a friend declaration specifies a
// default argument expression, that declaration shall be a definition
// and shall be the only declaration of the function or function
// template in the translation unit.

Not sure how wide spread this construct is, I’m seeing it for the first time. The code is not hard to fix and error seems appropriate to me.

It is in the top 10 of the build failure in the Debian rebuilds. So, it
is not uncommon.
Should we report a bug on gcc to have it more strict here? (or is it
"only" C++11)

S

Hello,

Thanks for the answer.

Can you clarify the clang description:
As I understand we should to move definition of the function to the header file, which contains declaration of the class and the friend function. Am I right? If so, I just think that this doesn’t better way.

The default argument should be on the original definition, not the
friend. I have fixed the cases I have seen in pkgsrc and mostly
submitted patches upstream, e.g. for Blender.

Joerg

Doesn't this also work:

// declaration with default argument comes first
int func1(int i, int j = 0);

class foo {
// friend decl doesn't use default arguments
friend int func1(int i, int j);
public:
    int func();
};

int foo::func() { return func1(1); }

// implementation in .cc file
int func1(int i, int j) { return i + j; }

int main() {
    foo a;
    a.func();
    return 0;
}