Порядок, в котором связаны библиотеки, имеет значение, если библиотеки зависят друг от друга. В общем, если библиотека A
зависит от библиотеки B
, то libA
ДОЛЖНЫ появляться перед libB
в флагах компоновщика.
Например:
// B.h
#ifndef B_H
#define B_H
struct B {
B(int);
int x;
};
#endif
// B.cpp
#include "B.h"
B::B(int xx) : x(xx) {}
// A.h
#include "B.h"
struct A {
A(int x);
B b;
};
// A.cpp
#include "A.h"
A::A(int x) : b(x) {}
// main.cpp
#include "A.h"
int main() {
A a(5);
return 0;
};
Создать библиотеки:
$ g++ -c A.cpp
$ g++ -c B.cpp
$ ar rvs libA.a A.o
ar: creating libA.a
a - A.o
$ ar rvs libB.a B.o
ar: creating libB.a
a - B.o
Скомпилировать:
$ g++ main.cpp -L. -lB -lA
./libA.a(A.o): In function `A::A(int)':
A.cpp:(.text+0x1c): undefined reference to `B::B(int)'
collect2: error: ld returned 1 exit status
$ g++ main.cpp -L. -lA -lB
$ ./a.out
Итак, повторить еще раз, порядок DOES важно!
Tail- Оптимизация вызова будет работать в Scala только в том случае, если рекурсивный вызов является последним оператором в функции. Это очень ограничено. В книге Scala говорится:
[...] оптимизация хвостового вызова - это ограничивается ситуациями, в которых метод или вложенная функция вызывает себя непосредственно как его последняя операция, не проходя через значение функции или какой-либо другой посредник.
В вашем случае рекурсивный вызов является частью более крупного выражения и сам по себе не является самой последней операцией - последней операцией здесь является умножение.
В этой статье показано, как это сделать заставить его работать:
class Factorial {
def factorial(n: Int): Int = {
def factorialAcc(acc: Int, n: Int): Int = {
if (n <= 1) acc
else factorialAcc(n * acc, n - 1)
}
factorialAcc(1, n)
}
}
В Scala 2.8 вы можете использовать аннотацию @tailrec, когда ожидаете, что должна использоваться оптимизация хвостового вызова, и получить предупреждение, если компилятор не может это сделать.