1

Why do gcc HEAD 10.0.0 20190 and Clang HEAD 9.0.0 both reject this program?

#include <iostream>

void g( int x )
{
    std::cout << "Hello g( " << x  << " )\n";
}

template <int N>
void g()
{
    std::cout << "Hello g<N>( " << N  << " )\n";
}

namespace N
{
    using ::g;
}

void g( int x = 20 );

template <int N = 10>
void g();

int main()
{
    N::g();
    N::g<>();
}

For example gcc issues the error

prog.cc: In function 'int main()':
prog.cc:27:11: error: no matching function for call to 'g()'
   27 |    N::g<>();
      |           ^
prog.cc:9:6: note: candidate: 'template<int N> void g()'
    9 | void g()
      |      ^
prog.cc:9:6: note:   template argument deduction/substitution failed:
prog.cc:27:11: note:   couldn't deduce template parameter 'N'
   27 |    N::g<>();
      |           ^

though according to the C++ 20 (and 17) Standard (9.8 The using declaration)

11 [Note: For a using-declaration whose nested-name-specifier names a namespace, members added to the namespace after the using-declaration are not in the set of introduced declarations, so they are not considered when a use of the name is made. Thus, additional overloads added after the using-declaration are ignored, but default function arguments (9.2.3.6), default template arguments (13.1), and template specializations (13.6.5, 13.8.3) are considered. — end note]

Based on my reading of the standard, I believe this is a bug.

Alex Reinking
  • 16,724
  • 5
  • 52
  • 86
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Clang does do the same though: https://godbolt.org/z/Rt_FLy – Max Langhof Aug 23 '19 at 15:36
  • @MaxLanghof I already tested it myself.:) – Vlad from Moscow Aug 23 '19 at 15:37
  • 1
    Well then I'm confused why this question is about gcc in particular. If it's a bug in gcc it's also a bug in clang... – Max Langhof Aug 23 '19 at 15:39
  • @MaxLanghof Because the version of gcc is 10.0.0 but of Clang that I tested is 9.0.0.:) There is no problem. I can mention also Clang in my question.:) – Vlad from Moscow Aug 23 '19 at 15:40
  • @MaxLanghof And you are mistaken that if a bug exists in gcc then it also exists in clang. It is a wrong assumption. – Vlad from Moscow Aug 23 '19 at 15:47
  • 1
    @VladfromMoscow the point of MaxLanghof is that it results in the same error in the HEAD of both gcc and clang. So if that error message in gcc is a bug, then this same error message in clang also has to be a bug. If you have a version of clang for which it works then you should tell which version (commit) it is. – t.niese Aug 23 '19 at 15:50
  • 3
    @VladfromMoscow No one said that both will/do always behave the same. But **this** code produces the same error in clang and gcc (current HEAD when writing that comment). The question is more why do you ask specifically about the compiler and not as `language-lawyer` question or something like that. And mentioning that it does not compile in gcc (and clang) even though you expect that it should. – t.niese Aug 23 '19 at 15:57
  • @t.niese You may add a tag as you like. – Vlad from Moscow Aug 23 '19 at 15:59

2 Answers2

6

This issue is the subject of Core issue 1907. The current direction is to treat such cases as ill-formed, no diagnostic required.

As it turns out, some implementations track default arguments on a "per-entity" basis (so it would be difficult to not consider default arguments added in a later redeclaration), while others track them on a "per-declaration" basis (so it would difficult to make them consider such default arguments). CWG decided to accommodate both implementation strategies by classifying code that depends on such things IFNDR.

T.C.
  • 133,968
  • 17
  • 288
  • 421
  • I see the date Date: 2014-03-30. However I presented a quote form the C++ 20 Standard Draft. – Vlad from Moscow Aug 23 '19 at 16:49
  • 4
    Yes, it takes time to draft and approve wording to fix a defect. Especially if there are higher priority items like actual features. – T.C. Aug 23 '19 at 16:50
0

I think the problem is that you're re-declaring the g<int> template function after implicitly declaring it during its definition.

This minimised example also fails to compile. Note no namespaces involved:

#include <iostream>

template <int N>
void g()
{
    std::cout << "Hello g<N>( " << N  << " )\n";
}

// redeclaration    
template <int N = 10>
void g();


int main()
{
    g<>();
}

whereas this compiles:

#include <iostream>


// declaration
template <int N = 10>
void g();

// definition
template <int N>
void g()
{
    std::cout << "Hello g<N>( " << N  << " )\n";
}


int main()
{
    g<>();
}
Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • This has nothing common with the quote from the C++ Standard I pointed out. – Vlad from Moscow Aug 23 '19 at 15:57
  • @vlad but it has lots in common with your code in the question. If it is ill formed without the using namespace, it will remain so with using namespace. The text of an.error from an ill formed program has no restrictions under the standard. – Yakk - Adam Nevraumont Aug 23 '19 at 16:54
  • @Yakk-AdamNevraumont I am sure it is a wrong analogy. The question about the compiler behavior relative to the using declaration. – Vlad from Moscow Aug 23 '19 at 16:55
  • @vlad yes, but if the code without the using declaration is ill formed, it remains ill formed after addong the using declaration, and without changing the example no conclusion about the using declaration addition can be made. – Yakk - Adam Nevraumont Aug 23 '19 at 18:39
  • @Yakk-AdamNevraumont No, the code without the using declaration is not ill-formed. Read the C++ Standard. – Vlad from Moscow Aug 24 '19 at 10:40
  • @vlad This answer contains the same code as yours, except without using the using declaration. And it fails to compile, again without your using declaration. Maybe you know something I and Richard do not, but at this point you haven't been very convincing. But no skin off my back. Bye! – Yakk - Adam Nevraumont Aug 24 '19 at 13:39
  • @Yakk-AdamNevraumont According to the C++ Standard you may use default template arguments with a template function. – Vlad from Moscow Aug 24 '19 at 13:42