Skip to content
Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

Why is a raven like a writing desk?

Thoughts both confusing and enlightening.

Clang/GCC weirdness

elbeno, 5 February, 201530 June, 2015

Consider the following code:

#include 
#include 
using namespace std;

// base template
template 
struct what_type
{
  void operator()()
  {
    cout << "T" << endl;
  }
};

// specialization 1
template 
struct what_type
{
  void operator()()
  {
    cout << "T[" << N << "]" << endl;
  }
};

// specialization 2
template <>
struct what_type
{
  void operator()()
  {
    cout << "int[0]" << endl;
  }
};

int main(void)
{
  int x[] = {};
  what_type>()();

  return 0;
}

I compile this with GCC (g++ (Ubuntu 4.9.1-16ubuntu6) 4.9.1) and I get:

bdeane@epsilon:~/dev/scratch$ g++ -std=c++1y main.cpp 
bdeane@epsilon:~/dev/scratch$ ./a.out
T

When I use clang (Ubuntu clang version 3.5.0-4ubuntu2 (tags/RELEASE_350/final) (based on LLVM 3.5.0)) I get:

bdeane@epsilon:~/dev/scratch$ clang++ -std=c++1y main.cpp 
bdeane@epsilon:~/dev/scratch$ ./a.out
int[0]

It seems GCC is wrong here: I would expect specialization 2 to be selected. Now, if I remove specialization 2, clang gives the same output as GCC (i.e. T).

If I put an assert in the base template member function, both clang and gcc think that T = int[0] and give almost identical messages:

a.out: main.cpp:53: void what_type<int [0]>::operator()() [T = int [0]]: Assertion `false' failed.

So why isn’t specialization 1 selected? (And it makes no difference either if I have a specialization for T[] as well as/instead of T[N].)

Edit:

Zero-sized arrays are illegal in C++, although GCC and Clang both compile them by default, presumably for historical reasons. If I turn on pedantic, both give me a warning.

From n4296 8.5.1 section 4:

An empty initializer list {} shall not be used as the initializer-clause for an array of unknown bound. (note 105)
105) The syntax provides for empty initializer-lists, but nonetheless C++ does not have zero length arrays.

So if GCC/Clang are going to allow zero-length arrays, I think they should be consistent about it and do specialization “correctly”. A friend reports that Clang/LLVM 3.3 does what GCC does here and uses the base template. Clang/LLVM 3.5 uses specialization 2, which is “more” correct. I have yet to try with Clang/LLVM 3.6+.

Edit 2:

Clang 3.7 produces the same output as clang 3.5.

C++ Programming

Post navigation

Previous post
Next post

Related Posts

Six languages worth knowing

6 December, 200718 July, 2008

“A language that doesn’t affect the way you think about programming, is not worth knowing” – Alan Perlis. I’ve thought about this, and developed a short list of languages worth knowing. Not-so-coincidentally, each language in my list embodies a distinct computational model. In no particular order: The ALGOL family. C…

Read More

Exercising Ranges (part 2)

1 July, 20151 July, 2015

(Start at the beginning of the series if you want more context.) First steps with power series A power series (or polynomial, to give it a more familiar term in the case where it’s finite) is represented simply as a sequence of coefficients of increasing powers of x. This is…

Read More

Why programming is fun

8 July, 200629 July, 2007

This week I have been working with a colleague on optimising a piece of code. Last week, what we started out with (a first implementation) was taking over 80ms to run in my test case. We had confidence that the overall algorithm was the correct one for the job, so…

Read More

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

©2026 Why is a raven like a writing desk? | WordPress Theme by SuperbThemes