Project

General

Profile

Bug #591

Problem with template instantiation and order of include directives

Added by John Abbott almost 10 years ago. Updated 3 months ago.

Status:
In Progress
Priority:
Low
Assignee:
-
Category:
Portability
Target version:
Start date:
16 Jul 2014
Due date:
% Done:

50%

Estimated time:
5.00 h
Spent time:

Description

Some versions of g++ (v4.3.2, v4.4.7, v4.6.3) and intel C++ compiler gave errors when compiling ex-UtilsVector1.C if, in the file degree.H, the #include directive for UtilsVector.H was placed before the other #include directives. The error produced indicated that some prototypes for cmp were not visible (in ptic for two @MachineInt@s).

We have no idea why, but since several compilers complain we wonder whether it isn't a strange limitation of C++.

Logging the problem here. The solution is just to move the #include directive in degree.H to after the other two.


Related issues

Related to CoCoALib - Bug #264: Compilation problem with "degree.H" (inline fn defns)Closed2012-10-12

History

#1 Updated by John Abbott almost 10 years ago

  • % Done changed from 0 to 10

JAA failed to find anything helpful on the internet.

I'm just hoping that the solution of moving the #include will be sufficient for the foreseeable future.

#2 Updated by John Abbott almost 10 years ago

Clang 3.0 on my computer gives no error.

#3 Updated by John Abbott over 7 years ago

  • Description updated (diff)

The problem persists with g++ 5.3.1. It must be C++ thing, some weird restriction about calling "global" fns from inside template code.

#4 Updated by John Abbott over 7 years ago

  • Status changed from New to In Progress

It really is a C++ trap for the unwary... grrr!

The following code fails to compile because the last line (iter(vs);) needs the second defn of func, but that is not visible at the point where the template fn was defined. I'm at a loss for words -- why does C++ have this "feature"???

#include <iostream>
#include <vector>
#include <string>

using namespace std;

void func(int n)
{
  cout << "int ";
}

template <typename T>
void iter(const std::vector<T>& v)
{
  const int n = v.size();
  for (int i=0; i < n; ++i)
    func(v[i]);
  cout << endl;
}

void func(const std::string& str)
{
  cout << "str ";
}

int main()
{
  vector<int> vi; vi.push_back(1);
  vector<string> vs; vs.push_back("abc");
  iter(vi);
  iter(vs);
}

#5 Updated by John Abbott over 7 years ago

There remains the question of how to correctly organize the header files in CoCoALib so that this "wonderful feature" of C++ does not cause too much grief.

#6 Updated by John Abbott over 7 years ago

Mario and I looked in Stroustrup's C++ book (v.4), and the magic phrase appears to be point-of-instantiation binding (sec. 26.3.3).

The matter is discussed on the following thread:
http://stackoverflow.com/questions/30514337/point-of-instantiation-and-name-binding
In summary, the point-of-instantiation binding apparently does not work for built-in C++ types; instead the point-of-definition binding is used. Grrr!

What I still do not know is how best to organize the few templates in CoCoALib header files to avoid future pain from these arcane C++ rules. Ideas are welcome!

#7 Updated by John Abbott about 4 years ago

  • Target version changed from CoCoALib-1.0 to CoCoALib-0.99850
  • % Done changed from 10 to 50

What should we do with this issue? The correct "solution" is for us to learn the foibles of C++.

It does highlight an important, awkward point of C++. We do not use templates that much, but I suppose it will sooner or later cause us grief again.

In practice... should we just close/reject this issue?

#8 Updated by John Abbott 3 months ago

  • Target version changed from CoCoALib-0.99850 to CoCoALib-1.0

Also available in: Atom PDF